2018-05-31 22:31:03 +00:00
|
|
|
// Copyright (c) 2004-present, Facebook, Inc.
|
|
|
|
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
|
|
// LICENSE file in the root directory of this source tree.
|
2016-05-04 02:29:58 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <functional>
|
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
|
2017-06-23 23:49:55 +00:00
|
|
|
#include <cxxreact/JSExecutor.h>
|
2016-11-01 18:38:43 +00:00
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
namespace folly {
|
|
|
|
struct dynamic;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace facebook {
|
|
|
|
namespace react {
|
|
|
|
|
2017-04-25 12:29:45 +00:00
|
|
|
struct InstanceCallback;
|
2017-06-23 23:49:55 +00:00
|
|
|
class JsToNativeBridge;
|
|
|
|
class MessageQueueThread;
|
|
|
|
class ModuleRegistry;
|
2017-09-22 16:56:50 +00:00
|
|
|
class RAMBundleRegistry;
|
2016-05-18 19:46:01 +00:00
|
|
|
|
|
|
|
// This class manages calls from native code to JS. It also manages
|
2016-09-26 23:01:42 +00:00
|
|
|
// executors and their threads. All functions here can be called from
|
|
|
|
// any thread.
|
|
|
|
//
|
|
|
|
// Except for loadApplicationScriptSync(), all void methods will queue
|
|
|
|
// work to run on the jsQueue passed to the ctor, and return
|
|
|
|
// immediately.
|
2016-05-18 19:46:01 +00:00
|
|
|
class NativeToJsBridge {
|
2016-05-04 02:29:58 +00:00
|
|
|
public:
|
2016-05-18 19:46:01 +00:00
|
|
|
friend class JsToNativeBridge;
|
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
/**
|
|
|
|
* This must be called on the main JS thread.
|
|
|
|
*/
|
2016-05-18 19:46:01 +00:00
|
|
|
NativeToJsBridge(
|
2016-05-04 02:29:58 +00:00
|
|
|
JSExecutorFactory* jsExecutorFactory,
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<ModuleRegistry> registry,
|
2016-05-04 02:29:58 +00:00
|
|
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<InstanceCallback> callback);
|
|
|
|
virtual ~NativeToJsBridge();
|
2016-05-04 02:29:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Executes a function with the module ID and method ID and any additional
|
|
|
|
* arguments in JS.
|
|
|
|
*/
|
2017-04-25 12:29:45 +00:00
|
|
|
void callFunction(std::string&& module, std::string&& method, folly::dynamic&& args);
|
2016-05-04 02:29:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Invokes a callback with the cbID, and optional additional arguments in JS.
|
|
|
|
*/
|
2017-04-25 12:29:45 +00:00
|
|
|
void invokeCallback(double callbackId, folly::dynamic&& args);
|
2016-05-04 02:29:58 +00:00
|
|
|
|
|
|
|
/**
|
2017-09-22 16:56:50 +00:00
|
|
|
* Starts the JS application. If bundleRegistry is non-null, then it is
|
2016-09-26 23:01:38 +00:00
|
|
|
* used to fetch JavaScript modules as individual scripts.
|
|
|
|
* Otherwise, the script is assumed to include all the modules.
|
2016-05-04 02:29:58 +00:00
|
|
|
*/
|
2016-09-26 23:01:38 +00:00
|
|
|
void loadApplication(
|
2017-09-22 16:56:50 +00:00
|
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
2016-09-26 23:01:38 +00:00
|
|
|
std::unique_ptr<const JSBigString> startupCode,
|
|
|
|
std::string sourceURL);
|
2016-09-26 23:01:42 +00:00
|
|
|
void loadApplicationSync(
|
2017-09-22 16:56:50 +00:00
|
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
2016-09-26 23:01:42 +00:00
|
|
|
std::unique_ptr<const JSBigString> startupCode,
|
|
|
|
std::string sourceURL);
|
2016-05-04 02:29:58 +00:00
|
|
|
|
2017-11-09 19:55:37 +00:00
|
|
|
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
|
2016-05-14 00:15:06 +00:00
|
|
|
void setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue);
|
2016-05-04 02:29:58 +00:00
|
|
|
void* getJavaScriptContext();
|
2017-12-18 21:19:37 +00:00
|
|
|
bool isInspectable();
|
2017-06-26 12:48:40 +00:00
|
|
|
|
|
|
|
void handleMemoryPressure(int pressureLevel);
|
2016-05-04 02:29:58 +00:00
|
|
|
|
2016-05-18 19:46:01 +00:00
|
|
|
/**
|
|
|
|
* Synchronously tears down the bridge and the main executor.
|
|
|
|
*/
|
|
|
|
void destroy();
|
|
|
|
private:
|
2017-04-25 12:29:45 +00:00
|
|
|
void runOnExecutorQueue(std::function<void(JSExecutor*)> task);
|
2016-05-18 19:46:01 +00:00
|
|
|
|
|
|
|
// This is used to avoid a race condition where a proxyCallback gets queued
|
|
|
|
// after ~NativeToJsBridge(), on the same thread. In that case, the callback
|
|
|
|
// will try to run the task on m_callback which will have been destroyed
|
|
|
|
// within ~NativeToJsBridge(), thus causing a SIGSEGV.
|
2016-05-04 02:29:58 +00:00
|
|
|
std::shared_ptr<bool> m_destroyed;
|
2016-05-18 19:46:01 +00:00
|
|
|
std::shared_ptr<JsToNativeBridge> m_delegate;
|
2017-04-25 12:29:45 +00:00
|
|
|
std::unique_ptr<JSExecutor> m_executor;
|
|
|
|
std::shared_ptr<MessageQueueThread> m_executorMessageQueueThread;
|
|
|
|
|
2016-05-04 02:29:58 +00:00
|
|
|
#ifdef WITH_FBSYSTRACE
|
|
|
|
std::atomic_uint_least32_t m_systraceCookie = ATOMIC_VAR_INIT();
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
} }
|