mirror of
https://github.com/status-im/react-native.git
synced 2025-02-25 07:35:25 +00:00
Expose way for native modules to modify JSC context
Reviewed By: svcscm Differential Revision: D2933197 fb-gh-sync-id: 32eb943ab341804343bbcadd29f0377fccf75de6 shipit-source-id: 32eb943ab341804343bbcadd29f0377fccf75de6
This commit is contained in:
parent
46a8f1d8e0
commit
e5ba46c30d
@ -16,6 +16,15 @@
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJSCThreadName;
|
||||
|
||||
/**
|
||||
* This notification fires on the JS thread immediately after a `JSContext`
|
||||
* is fully initialized, but before the JS bundle has been loaded. The object
|
||||
* of this notification is the `JSContext`. Native modules should listen for
|
||||
* notification only if they need to install custom functionality into the
|
||||
* context. Note that this notification won't fire when debugging in Chrome.
|
||||
*/
|
||||
RCT_EXTERN NSString *const RCTJavaScriptContextCreatedNotification;
|
||||
|
||||
/**
|
||||
* Uses a JavaScriptCore context as the execution engine.
|
||||
*/
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
NSString *const RCTJSCThreadName = @"com.facebook.React.JavaScript";
|
||||
|
||||
NSString *const RCTJavaScriptContextCreatedNotification = @"RCTJavaScriptContextCreatedNotification";
|
||||
|
||||
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
||||
|
||||
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
||||
@ -332,7 +334,16 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||
}];
|
||||
|
||||
[self executeBlockOnJavaScriptQueue:^{
|
||||
RCTInstallJSCProfiler(_bridge, self.context.ctx);
|
||||
RCTJSCExecutor *strongSelf = weakSelf;
|
||||
if (!strongSelf.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext *context = strongSelf.context.context;
|
||||
RCTInstallJSCProfiler(_bridge, context.JSGlobalContextRef);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptContextCreatedNotification
|
||||
object:context];
|
||||
}];
|
||||
|
||||
for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) {
|
||||
|
@ -332,6 +332,11 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReactBridgeInitialized(ReactBridge bridge) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCatalystInstanceDestroy() {
|
||||
// do nothing
|
||||
|
@ -127,6 +127,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
|
||||
mJavaRegistry.notifyReactBridgeInitialized(bridge);
|
||||
return bridge;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,15 @@ public interface NativeModule {
|
||||
*/
|
||||
boolean canOverrideExistingModule();
|
||||
|
||||
/**
|
||||
* Called on the JS thread after a ReactBridge has been created. This is useful for native modules
|
||||
* that need to do any setup before the JS bundle has been loaded. An example of this would be
|
||||
* installing custom functionality into the JavaScriptCore context.
|
||||
*
|
||||
* @param bridge the ReactBridge instance that has just been created
|
||||
*/
|
||||
void onReactBridgeInitialized(ReactBridge bridge);
|
||||
|
||||
/**
|
||||
* Called before {CatalystInstance#onHostDestroy}
|
||||
*/
|
||||
|
@ -114,6 +114,19 @@ public class NativeModuleRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void notifyReactBridgeInitialized(ReactBridge bridge) {
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||
"NativeModuleRegistry_notifyReactBridgeInitialized");
|
||||
try {
|
||||
for (NativeModule nativeModule : mModuleInstances.values()) {
|
||||
nativeModule.onReactBridgeInitialized(bridge);
|
||||
}
|
||||
} finally {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBatchComplete() {
|
||||
for (int i = 0; i < mBatchCompleteListenerModules.size(); i++) {
|
||||
mBatchCompleteListenerModules.get(i).onBatchComplete();
|
||||
|
@ -87,4 +87,13 @@ public class ReactBridge extends Countable {
|
||||
public native void stopProfiler(String title, String filename);
|
||||
private native void handleMemoryPressureModerate();
|
||||
private native void handleMemoryPressureCritical();
|
||||
|
||||
/**
|
||||
* This method will return a long representing the underlying JSGlobalContextRef pointer or
|
||||
* 0 (representing NULL) when in Chrome debug mode, and is only useful if passed back through
|
||||
* the JNI to native code that will use it with the JavaScriptCore C API.
|
||||
* **WARNING:** This method is *experimental* and should only be used when no other option is
|
||||
* available. It will likely change in a future release!
|
||||
*/
|
||||
public native long getJavaScriptContextNativePtrExperimental();
|
||||
}
|
||||
|
@ -57,6 +57,10 @@ void Bridge::setGlobalVariable(const std::string& propName, const std::string& j
|
||||
m_mainExecutor->setGlobalVariable(propName, jsonValue);
|
||||
}
|
||||
|
||||
void* Bridge::getJavaScriptContext() {
|
||||
return m_mainExecutor->getJavaScriptContext();
|
||||
}
|
||||
|
||||
bool Bridge::supportsProfiling() {
|
||||
return m_mainExecutor->supportsProfiling();
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
const std::string& startupCode,
|
||||
const std::string& sourceURL);
|
||||
void setGlobalVariable(const std::string& propName, const std::string& jsonValue);
|
||||
void* getJavaScriptContext();
|
||||
bool supportsProfiling();
|
||||
void startProfiler(const std::string& title);
|
||||
void stopProfiler(const std::string& title, const std::string& filename);
|
||||
|
@ -60,6 +60,9 @@ public:
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) = 0;
|
||||
virtual void* getJavaScriptContext() {
|
||||
return nullptr;
|
||||
};
|
||||
virtual bool supportsProfiling() {
|
||||
return false;
|
||||
};
|
||||
|
@ -198,6 +198,10 @@ void JSCExecutor::setGlobalVariable(const std::string& propName, const std::stri
|
||||
JSObjectSetProperty(m_context, globalObject, jsPropertyName, valueToInject, 0, NULL);
|
||||
}
|
||||
|
||||
void* JSCExecutor::getJavaScriptContext() {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
bool JSCExecutor::supportsProfiling() {
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
return true;
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
virtual void setGlobalVariable(
|
||||
const std::string& propName,
|
||||
const std::string& jsonValue) override;
|
||||
virtual void* getJavaScriptContext() override;
|
||||
virtual bool supportsProfiling() override;
|
||||
virtual void startProfiler(const std::string &titleString) override;
|
||||
virtual void stopProfiler(const std::string &titleString, const std::string &filename) override;
|
||||
|
@ -760,6 +760,11 @@ static void setGlobalVariable(JNIEnv* env, jobject obj, jstring propName, jstrin
|
||||
bridge->setGlobalVariable(fromJString(env, propName), fromJString(env, jsonValue));
|
||||
}
|
||||
|
||||
static jlong getJavaScriptContext(JNIEnv *env, jobject obj) {
|
||||
auto bridge = extractRefPtr<CountableBridge>(env, obj);
|
||||
return (uintptr_t) bridge->getJavaScriptContext();
|
||||
}
|
||||
|
||||
static jboolean supportsProfiling(JNIEnv* env, jobject obj) {
|
||||
auto bridge = extractRefPtr<CountableBridge>(env, obj);
|
||||
return bridge->supportsProfiling() ? JNI_TRUE : JNI_FALSE;
|
||||
@ -944,7 +949,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
makeNativeMethod("stopProfiler", bridge::stopProfiler),
|
||||
makeNativeMethod("handleMemoryPressureModerate", bridge::handleMemoryPressureModerate),
|
||||
makeNativeMethod("handleMemoryPressureCritical", bridge::handleMemoryPressureCritical),
|
||||
|
||||
makeNativeMethod("getJavaScriptContextNativePtrExperimental", bridge::getJavaScriptContext),
|
||||
});
|
||||
|
||||
jclass nativeRunnableClass = env->FindClass("com/facebook/react/bridge/queue/NativeRunnableDeprecated");
|
||||
|
Loading…
x
Reference in New Issue
Block a user