static void ScanModulesAtPath(string path, vector<SharedComponent>& results, bool bundled) { if (!FileUtils::IsDirectory(path)) return; // Read everything that looks like <searchpath>/modules/<os>/* string namesPath(FileUtils::Join(path.c_str(), "modules", 0)); if (!bundled) namesPath = FileUtils::Join(namesPath.c_str(), OS_NAME, 0); vector<PathBits> moduleNames(GetDirectoriesAtPath(namesPath)); for (size_t i = 0; i < moduleNames.size(); i++) { PathBits& moduleName = moduleNames[i]; // Read everything that looks like <searchpath>/modules/<os>/<name>/* vector<PathBits> moduleVersions(GetDirectoriesAtPath(moduleName.fullPath)); for (size_t j = 0; j < moduleVersions.size(); j++) { PathBits& moduleVersion = moduleVersions[j]; AddToComponentVector(results, KComponent::NewComponent( MODULE, moduleName.name, moduleVersion.name, moduleVersion.fullPath, bundled)); } } }
folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name) { SystraceSection s("getConfig", "module", name); // Initialize modulesByName_ if (modulesByName_.empty() && !modules_.empty()) { moduleNames(); } auto it = modulesByName_.find(name); if (it == modulesByName_.end()) { return nullptr; } CHECK(it->second < modules_.size()); NativeModule* module = modules_[it->second].get(); // string name, object constants, array methodNames (methodId is index), [array promiseMethodIds], [array syncMethodIds] folly::dynamic config = folly::dynamic::array(name); { SystraceSection s_("getConstants"); config.push_back(module->getConstants()); } { SystraceSection s_("getMethods"); std::vector<MethodDescriptor> methods = module->getMethods(); folly::dynamic methodNames = folly::dynamic::array; folly::dynamic promiseMethodIds = folly::dynamic::array; folly::dynamic syncMethodIds = folly::dynamic::array; for (auto& descriptor : methods) { // TODO: #10487027 compare tags instead of doing string comparison? methodNames.push_back(std::move(descriptor.name)); if (descriptor.type == "promise") { promiseMethodIds.push_back(methodNames.size() - 1); } else if (descriptor.type == "sync") { syncMethodIds.push_back(methodNames.size() - 1); } } if (!methodNames.empty()) { config.push_back(std::move(methodNames)); if (!promiseMethodIds.empty() || !syncMethodIds.empty()) { config.push_back(std::move(promiseMethodIds)); if (!syncMethodIds.empty()) { config.push_back(std::move(syncMethodIds)); } } } } if (config.size() == 2 && config[1].empty()) { // no constants or methods return nullptr; } else { return ModuleConfig({it->second, config}); } }
ProxyExecutor::ProxyExecutor(jni::global_ref<jobject>&& executorInstance, std::shared_ptr<ExecutorDelegate> delegate) : m_executor(std::move(executorInstance)) , m_delegate(delegate) { folly::dynamic nativeModuleConfig = folly::dynamic::array; { SystraceSection s("collectNativeModuleDescriptions"); auto moduleRegistry = delegate->getModuleRegistry(); for (const auto& name : moduleRegistry->moduleNames()) { auto config = moduleRegistry->getConfig(name); nativeModuleConfig.push_back(config ? config->config : nullptr); } } folly::dynamic config = folly::dynamic::object ("remoteModuleConfig", std::move(nativeModuleConfig)); SystraceSection t("setGlobalVariable"); setGlobalVariable( "__fbBatchedBridgeConfig", folly::make_unique<JSBigStdString>(folly::toJson(config))); }
void ProxyExecutor::loadApplicationScript( std::unique_ptr<const JSBigString>, std::string sourceURL) { folly::dynamic nativeModuleConfig = folly::dynamic::array; { SystraceSection s("collectNativeModuleDescriptions"); auto moduleRegistry = m_delegate->getModuleRegistry(); for (const auto& name : moduleRegistry->moduleNames()) { auto config = moduleRegistry->getConfig(name); nativeModuleConfig.push_back(config ? config->config : nullptr); } } folly::dynamic config = folly::dynamic::object ("remoteModuleConfig", std::move(nativeModuleConfig)); { SystraceSection t("setGlobalVariable"); setGlobalVariable( "__fbBatchedBridgeConfig", folly::make_unique<JSBigStdString>(folly::toJson(config))); } static auto loadApplicationScript = jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring)>("loadApplicationScript"); // The proxy ignores the script data passed in. loadApplicationScript( m_executor.get(), jni::make_jstring(sourceURL).get()); // We can get pending calls here to native but the queue will be drained when // we launch the application. }