Skip to content

Commit bef7967

Browse files
bnhamfacebook-github-bot
authored andcommitted
move page registration logic in to jsinspector
Reviewed By: pakoito Differential Revision: D6531199 fbshipit-source-id: ed1ae9e2f0c19e7656cd022e438693798320e55a
1 parent 48019a0 commit bef7967

File tree

10 files changed

+147
-39
lines changed

10 files changed

+147
-39
lines changed

React/Inspector/RCTInspector.mm

+1-9
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,9 @@ @interface RCTInspectorLocalConnection () {
4949
- (instancetype)initWithConnection:(std::unique_ptr<ILocalConnection>)connection;
5050
@end
5151

52-
// Only safe to call with Custom JSC. Custom JSC check must occur earlier
53-
// in the stack
5452
static IInspector *getInstance()
5553
{
56-
static dispatch_once_t onceToken;
57-
static IInspector *s_inspector;
58-
dispatch_once(&onceToken, ^{
59-
s_inspector = customJSCWrapper()->JSInspectorGetInstance();
60-
});
61-
62-
return s_inspector;
54+
return &facebook::react::getInspectorInstance();
6355
}
6456

6557
@implementation RCTInspector

ReactAndroid/src/main/jni/react/jni/JInspector.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,8 @@ void JLocalConnection::registerNatives() {
6161
});
6262
}
6363

64-
static IInspector* getInspectorInstance() {
65-
return JSC_JSInspectorGetInstance(true /*useCustomJSC*/);
66-
}
67-
6864
jni::global_ref<JInspector::javaobject> JInspector::instance(jni::alias_ref<jclass>) {
69-
static auto instance = jni::make_global(newObjectCxxArgs(getInspectorInstance()/*&Inspector::instance()*/));
65+
static auto instance = jni::make_global(newObjectCxxArgs(&getInspectorInstance()));
7066
return instance;
7167
}
7268

ReactCommon/cxxreact/JSCExecutor.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,12 @@ namespace facebook {
215215
const std::string ownerId = m_jscConfig.getDefault("OwnerIdentity", "unknown").getString();
216216
const std::string appId = m_jscConfig.getDefault("AppIdentity", "unknown").getString();
217217
const std::string deviceId = m_jscConfig.getDefault("DeviceIdentity", "unknown").getString();
218-
const std::function<bool()> checkIsInspectedRemote = [&](){
218+
auto checkIsInspectedRemote = [ownerId, appId, deviceId]() {
219219
return isNetworkInspected(ownerId, appId, deviceId);
220220
};
221-
IInspector* pInspector = JSC_JSInspectorGetInstance(true);
222-
pInspector->registerGlobalContext(ownerId, checkIsInspectedRemote, m_context);
221+
222+
auto& globalInspector = facebook::react::getInspectorInstance();
223+
JSC_JSGlobalContextEnableDebugger(m_context, globalInspector, ownerId.c_str(), checkIsInspectedRemote);
223224
}
224225

225226
installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate");
@@ -340,8 +341,8 @@ namespace facebook {
340341
m_nativeModules.reset();
341342

342343
if (canUseInspector(context)) {
343-
IInspector* pInspector = JSC_JSInspectorGetInstance(true);
344-
pInspector->unregisterGlobalContext(context);
344+
auto &globalInspector = facebook::react::getInspectorInstance();
345+
JSC_JSGlobalContextDisableDebugger(context, globalInspector);
345346
}
346347

347348
JSC_JSGlobalContextRelease(context);

ReactCommon/cxxreact/JSCExecutor.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class RN_EXPORT JSCExecutor : public JSExecutor, public PrivateDataBase {
117117
folly::Optional<Object> m_callFunctionReturnResultAndFlushedQueueJS;
118118

119119
void initOnJSVMThread() throw(JSException);
120-
bool isNetworkInspected(const std::string &owner, const std::string &app, const std::string &device);
120+
static bool isNetworkInspected(const std::string &owner, const std::string &app, const std::string &device);
121121
// This method is experimental, and may be modified or removed.
122122
Value callFunctionSyncWithValue(
123123
const std::string& module, const std::string& method, Value value);

ReactCommon/jschelpers/JSCWrapper.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#pragma once
1111

12+
#include <functional>
1213
#include <string>
1314
#include <JavaScriptCore/JavaScript.h>
1415

@@ -32,7 +33,14 @@ namespace react {
3233
}
3334
}
3435

35-
JSC_IMPORT facebook::react::IInspector* JSInspectorGetInstance();
36+
JSC_IMPORT void JSGlobalContextEnableDebugger(
37+
JSGlobalContextRef ctx,
38+
facebook::react::IInspector &globalInspector,
39+
const char *title,
40+
const std::function<bool()> &checkIsInspectedRemote);
41+
JSC_IMPORT void JSGlobalContextDisableDebugger(
42+
JSGlobalContextRef ctx,
43+
facebook::react::IInspector &globalInspector);
3644

3745
// This is used to substitute an alternate JSC implementation for
3846
// testing. These calls must all be ABI compatible with the standard JSC.
@@ -143,7 +151,8 @@ struct JSCWrapper {
143151
JSC_WRAPPER_METHOD(JSPokeSamplingProfiler);
144152
JSC_WRAPPER_METHOD(JSStartSamplingProfilingOnMainJSCThread);
145153

146-
JSC_WRAPPER_METHOD(JSInspectorGetInstance);
154+
JSC_WRAPPER_METHOD(JSGlobalContextEnableDebugger);
155+
JSC_WRAPPER_METHOD(JSGlobalContextDisableDebugger);
147156

148157
JSC_WRAPPER_METHOD(configureJSCForIOS);
149158

ReactCommon/jschelpers/JavaScriptCore.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,13 @@ jsc_poison(JSObjectMakeArrayBufferWithBytesNoCopy JSObjectMakeTypedArray
191191
jsc_poison(JSSamplingProfilerEnabled JSPokeSamplingProfiler
192192
JSStartSamplingProfilingOnMainJSCThread)
193193

194-
#define JSC_JSInspectorGetInstance(...) __jsc_bool_wrapper(JSInspectorGetInstance, __VA_ARGS__)
195-
// no need to poison JSInspectorGetInstance because it's not defined for System JSC / standard SDK header
196-
// jsc_poison(JSInspectorGetInstance)
194+
#define JSC_JSGlobalContextEnableDebugger(...) __jsc_wrapper(JSGlobalContextEnableDebugger, __VA_ARGS__)
195+
// no need to poison JSGlobalContextEnableDebugger because it's not defined for System JSC / standard SDK header
196+
// jsc_poison(JSGlobalContextEnableDebugger)
197+
198+
#define JSC_JSGlobalContextDisableDebugger(...) __jsc_wrapper(JSGlobalContextDisableDebugger, __VA_ARGS__)
199+
// no need to poison JSGlobalContextDisableDebugger because it's not defined for System JSC / standard SDK header
200+
// jsc_poison(JSGlobalContextDisableDebugger)
197201

198202

199203
#define JSC_configureJSCForIOS(...) __jsc_bool_wrapper(configureJSCForIOS, __VA_ARGS__)

ReactCommon/jschelpers/systemJSCWrapper.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSStringCreateWithUTF8CStringExpectAscii)
2929
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSPokeSamplingProfiler)
3030
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSStartSamplingProfilingOnMainJSCThread)
3131

32-
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSInspectorGetInstance)
32+
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSGlobalContextEnableDebugger)
33+
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(JSGlobalContextDisableDebugger)
3334

3435
UNIMPLEMENTED_SYSTEM_JSC_FUNCTION(configureJSCForIOS)
3536

@@ -129,9 +130,12 @@ const JSCWrapper* systemJSCWrapper() {
129130
(decltype(&JSStartSamplingProfilingOnMainJSCThread))
130131
Unimplemented_JSStartSamplingProfilingOnMainJSCThread,
131132

132-
.JSInspectorGetInstance =
133-
(decltype(&JSInspectorGetInstance))
134-
Unimplemented_JSInspectorGetInstance,
133+
.JSGlobalContextEnableDebugger =
134+
(decltype(&JSGlobalContextEnableDebugger))
135+
Unimplemented_JSGlobalContextEnableDebugger,
136+
.JSGlobalContextDisableDebugger =
137+
(decltype(&JSGlobalContextDisableDebugger))
138+
Unimplemented_JSGlobalContextDisableDebugger,
135139

136140
.configureJSCForIOS =
137141
(decltype(&configureJSCForIOS))Unimplemented_configureJSCForIOS,

ReactCommon/jsinspector/BUCK

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rn_xplat_cxx_library(
2020
"-fexceptions",
2121
"-std=c++1y",
2222
],
23+
fbandroid_preferred_linkage = "shared",
2324
visibility = [
2425
"PUBLIC",
2526
],

ReactCommon/jsinspector/InspectorInterfaces.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
#include "InspectorInterfaces.h"
1111

12+
#include <mutex>
13+
#include <unordered_map>
14+
1215
namespace facebook {
1316
namespace react {
1417

@@ -19,5 +22,80 @@ IDestructible::~IDestructible() { }
1922
ILocalConnection::~ILocalConnection() { }
2023
IRemoteConnection::~IRemoteConnection() { }
2124

25+
namespace {
26+
27+
class InspectorImpl : public IInspector {
28+
public:
29+
int addPage(const std::string& title, ConnectFunc connectFunc) override;
30+
void removePage(int pageId) override;
31+
32+
std::vector<InspectorPage> getPages() const override;
33+
std::unique_ptr<ILocalConnection> connect(
34+
int pageId,
35+
std::unique_ptr<IRemoteConnection> remote) override;
36+
37+
private:
38+
mutable std::mutex mutex_;
39+
int nextPageId_{1};
40+
std::unordered_map<int, std::string> titles_;
41+
std::unordered_map<int, ConnectFunc> connectFuncs_;
42+
};
43+
44+
int InspectorImpl::addPage(const std::string& title, ConnectFunc connectFunc) {
45+
std::lock_guard<std::mutex> lock(mutex_);
46+
47+
int pageId = nextPageId_++;
48+
titles_[pageId] = title;
49+
connectFuncs_[pageId] = std::move(connectFunc);
50+
51+
return pageId;
52+
}
53+
54+
void InspectorImpl::removePage(int pageId) {
55+
std::lock_guard<std::mutex> lock(mutex_);
56+
57+
titles_.erase(pageId);
58+
connectFuncs_.erase(pageId);
59+
}
60+
61+
std::vector<InspectorPage> InspectorImpl::getPages() const {
62+
std::lock_guard<std::mutex> lock(mutex_);
63+
64+
std::vector<InspectorPage> inspectorPages;
65+
for (auto& it : titles_) {
66+
inspectorPages.push_back(InspectorPage{it.first, it.second});
67+
}
68+
69+
return inspectorPages;
70+
}
71+
72+
std::unique_ptr<ILocalConnection> InspectorImpl::connect(
73+
int pageId,
74+
std::unique_ptr<IRemoteConnection> remote) {
75+
IInspector::ConnectFunc connectFunc;
76+
77+
{
78+
std::lock_guard<std::mutex> lock(mutex_);
79+
80+
auto it = connectFuncs_.find(pageId);
81+
if (it != connectFuncs_.end()) {
82+
connectFunc = it->second;
83+
}
84+
}
85+
86+
return connectFunc ? connectFunc(std::move(remote)) : nullptr;
87+
}
88+
89+
} // namespace
90+
91+
IInspector& getInspectorInstance() {
92+
static InspectorImpl instance;
93+
return instance;
2294
}
95+
96+
std::unique_ptr<IInspector> makeTestInspectorInstance() {
97+
return std::make_unique<InspectorImpl>();
2398
}
99+
100+
} // namespace react
101+
} // namespace facebook

ReactCommon/jsinspector/InspectorInterfaces.h

+33-10
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace facebook {
1818
namespace react {
1919

2020
class IDestructible {
21-
public:
21+
public:
2222
virtual ~IDestructible() = 0;
2323
};
2424

@@ -27,29 +27,52 @@ struct InspectorPage {
2727
const std::string title;
2828
};
2929

30+
/// IRemoteConnection allows the VM to send debugger messages to the client.
3031
class IRemoteConnection : public IDestructible {
31-
public:
32+
public:
3233
virtual ~IRemoteConnection() = 0;
3334
virtual void onMessage(std::string message) = 0;
3435
virtual void onDisconnect() = 0;
3536
};
3637

38+
/// ILocalConnection allows the client to send debugger messages to the VM.
3739
class ILocalConnection : public IDestructible {
38-
public:
40+
public:
3941
virtual ~ILocalConnection() = 0;
4042
virtual void sendMessage(std::string message) = 0;
4143
virtual void disconnect() = 0;
4244
};
4345

44-
// Note: not destructible!
46+
/// IInspector tracks debuggable JavaScript targets (pages).
4547
class IInspector {
46-
public:
47-
virtual void registerGlobalContext(const std::string& title, const std::function<bool()> &checkIsInspectedRemote, void* ctx) = 0;
48-
virtual void unregisterGlobalContext(void* ctx) = 0;
48+
public:
49+
using ConnectFunc = std::function<std::unique_ptr<ILocalConnection>(
50+
std::unique_ptr<IRemoteConnection>)>;
4951

52+
/// addPage is called by the VM to add a page to the list of debuggable pages.
53+
virtual int addPage(const std::string& title, ConnectFunc connectFunc) = 0;
54+
55+
/// removePage is called by the VM to remove a page from the list of
56+
/// debuggable pages.
57+
virtual void removePage(int pageId) = 0;
58+
59+
/// getPages is called by the client to list all debuggable pages.
5060
virtual std::vector<InspectorPage> getPages() const = 0;
51-
virtual std::unique_ptr<ILocalConnection> connect(int pageId, std::unique_ptr<IRemoteConnection> remote) = 0;
61+
62+
/// connect is called by the client to initiate a debugging session on the
63+
/// given page.
64+
virtual std::unique_ptr<ILocalConnection> connect(
65+
int pageId,
66+
std::unique_ptr<IRemoteConnection> remote) = 0;
5267
};
5368

54-
}
55-
}
69+
/// getInspectorInstance retrieves the singleton inspector that tracks all
70+
/// debuggable pages in this process.
71+
extern IInspector& getInspectorInstance();
72+
73+
/// makeTestInspectorInstance creates an independent inspector instance that
74+
/// should only be used in tests.
75+
extern std::unique_ptr<IInspector> makeTestInspectorInstance();
76+
77+
} // namespace react
78+
} // namespace facebook

0 commit comments

Comments
 (0)