From b5651d945cd6f30402b7edbcfb49983159080a47 Mon Sep 17 00:00:00 2001 From: Alex Dvornikov Date: Wed, 1 Nov 2017 06:33:37 -0700 Subject: [PATCH] Add "setJsBundlesDirectory" method to CatalystInstanceImpl Differential Revision: D6042493 fbshipit-source-id: 950c6d6bdc2e0b62b14c9bcfc86233159a002c67 --- .../react/bridge/CatalystInstanceImpl.java | 5 +++++ .../facebook/react/bridge/JSBundleLoader.java | 16 ++++++++++++++-- .../main/jni/react/jni/CatalystInstanceImpl.cpp | 15 ++++++++++++--- .../main/jni/react/jni/CatalystInstanceImpl.h | 8 ++++++++ .../main/jni/react/jni/JniRAMBundleRegistry.cpp | 4 ++-- .../main/jni/react/jni/JniRAMBundleRegistry.h | 2 +- ReactCommon/cxxreact/RAMBundleRegistry.cpp | 15 --------------- ReactCommon/cxxreact/RAMBundleRegistry.h | 1 - 8 files changed, 42 insertions(+), 24 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index 3c65139a7d0..c0aacb67a2a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -210,6 +210,10 @@ public class CatalystInstanceImpl implements CatalystInstance { jniSetSourceURL(remoteURL); } + /* package */ void setJsBundlesDirectory(String directoryPath) { + jniSetJsBundlesDirectory(directoryPath); + } + /* package */ void loadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously) { mSourceURL = assetURL; jniLoadScriptFromAssets(assetManager, assetURL, loadSynchronously); @@ -221,6 +225,7 @@ public class CatalystInstanceImpl implements CatalystInstance { } private native void jniSetSourceURL(String sourceURL); + private native void jniSetJsBundlesDirectory(String directoryPath); private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously); private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously); diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java index 0597dc8f109..0c5476bbfe6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java @@ -10,7 +10,6 @@ package com.facebook.react.bridge; import android.content.Context; - import com.facebook.react.common.DebugServerException; /** @@ -98,7 +97,20 @@ public abstract class JSBundleLoader { } /** - * Loads the script, returning the URL of the source it loaded. + * This loader is used to wrap other loaders and set js bundles directory before executing + * application script. */ + public static JSBundleLoader createSplitBundlesLoader( + final String jsBundlesDirectory, final JSBundleLoader delegate) { + return new JSBundleLoader() { + @Override + public String loadScript(CatalystInstanceImpl instance) { + instance.setJsBundlesDirectory(jsBundlesDirectory); + return delegate.loadScript(instance); + } + }; + } + + /** Loads the script, returning the URL of the source it loaded. */ public abstract String loadScript(CatalystInstanceImpl instance); } diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 73571877adc..4ce97ac8745 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -10,10 +10,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -101,6 +101,7 @@ void CatalystInstanceImpl::registerNatives() { makeNativeMethod("initializeBridge", CatalystInstanceImpl::initializeBridge), makeNativeMethod("jniExtendNativeModules", CatalystInstanceImpl::extendNativeModules), makeNativeMethod("jniSetSourceURL", CatalystInstanceImpl::jniSetSourceURL), + makeNativeMethod("jniSetJsBundlesDirectory", CatalystInstanceImpl::jniSetJsBundlesDirectory), makeNativeMethod("jniLoadScriptFromAssets", CatalystInstanceImpl::jniLoadScriptFromAssets), makeNativeMethod("jniLoadScriptFromFile", CatalystInstanceImpl::jniLoadScriptFromFile), makeNativeMethod("jniCallJSFunction", CatalystInstanceImpl::jniCallJSFunction), @@ -177,6 +178,10 @@ void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) { instance_->setSourceURL(sourceURL); } +void CatalystInstanceImpl::jniSetJsBundlesDirectory(const std::string& directoryPath) { + jsBundlesDirectory_ = directoryPath; +} + void CatalystInstanceImpl::jniLoadScriptFromAssets( jni::alias_ref assetManager, const std::string& assetURL, @@ -188,7 +193,9 @@ void CatalystInstanceImpl::jniLoadScriptFromAssets( auto script = loadScriptFromAssets(manager, sourceURL); if (JniJSModulesUnbundle::isUnbundle(manager, sourceURL)) { auto bundle = JniJSModulesUnbundle::fromEntryFile(manager, sourceURL); - auto registry = folly::make_unique(std::move(bundle), manager, sourceURL); + auto registry = jsBundlesDirectory_.empty() + ? folly::make_unique(std::move(bundle)) + : folly::make_unique(std::move(bundle), manager, sourceURL); instance_->loadRAMBundle( std::move(registry), std::move(script), @@ -218,7 +225,9 @@ void CatalystInstanceImpl::jniLoadScriptFromFile(const std::string& fileName, if (isIndexedRAMBundle(zFileName)) { auto bundle = folly::make_unique(zFileName); auto startupScript = bundle->getStartupCode(); - auto registry = folly::make_unique(std::move(bundle)); + auto registry = jsBundlesDirectory_.empty() + ? folly::make_unique(std::move(bundle)) + : folly::make_unique(std::move(bundle), jsBundlesDirectory_); instance_->loadRAMBundle( std::move(registry), std::move(startupScript), diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index 63034daa408..1c481a83535 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -61,6 +61,12 @@ class CatalystInstanceImpl : public jni::HybridClass { */ void jniSetSourceURL(const std::string& sourceURL); + /** + * Sets the path to folder where additional bundles are located. + * Needs to be invoked before "loadScript" methods are called. + */ + void jniSetJsBundlesDirectory(const std::string& directoryPath); + void jniLoadScriptFromAssets(jni::alias_ref assetManager, const std::string& assetURL, bool loadSynchronously); void jniLoadScriptFromFile(const std::string& fileName, const std::string& sourceURL, bool loadSynchronously); void jniCallJSFunction(std::string module, std::string method, NativeArray* arguments); @@ -70,6 +76,8 @@ class CatalystInstanceImpl : public jni::HybridClass { jlong getJavaScriptContext(); void handleMemoryPressure(int pressureLevel); + std::string jsBundlesDirectory_; + // This should be the only long-lived strong reference, but every C++ class // will have a weak reference. std::shared_ptr instance_; diff --git a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp index 01c907d4397..3f2219a20f5 100644 --- a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp @@ -10,10 +10,10 @@ namespace facebook { namespace react { -JniRAMBundleRegistry::JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& entryFile) : +JniRAMBundleRegistry::JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& baseDirectoryPath) : RAMBundleRegistry(std::move(mainBundle)), m_assetManager(assetManager), - m_baseDirectoryPath(jsBundlesDir(entryFile)) {} + m_baseDirectoryPath(baseDirectoryPath) {} std::unique_ptr JniRAMBundleRegistry::bundleById(uint32_t index) const { std::string bundlePathById = m_baseDirectoryPath + folly::to(index) + "/js-modules/"; diff --git a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h index ce27f86356f..255fa89e2ed 100644 --- a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h +++ b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h @@ -8,7 +8,7 @@ namespace react { class JniRAMBundleRegistry : public RAMBundleRegistry { public: - JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& entryFile); + JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& baseDirectoryPath); protected: virtual std::unique_ptr bundleById(uint32_t index) const override; diff --git a/ReactCommon/cxxreact/RAMBundleRegistry.cpp b/ReactCommon/cxxreact/RAMBundleRegistry.cpp index 6b88a155a64..5159475bb41 100644 --- a/ReactCommon/cxxreact/RAMBundleRegistry.cpp +++ b/ReactCommon/cxxreact/RAMBundleRegistry.cpp @@ -25,20 +25,5 @@ JSModulesUnbundle *RAMBundleRegistry::getBundle(uint32_t bundleId) const { return m_bundles.at(bundleId).get(); } -std::string RAMBundleRegistry::jsBundlesDir(std::string entryFile) { - char *pEntryFile = const_cast(entryFile.c_str()); - std::string dir = dirname(pEntryFile); - std::string entryName = basename(pEntryFile); - - std::size_t dotPosition = entryName.find("."); - if (dotPosition != std::string::npos) { - entryName.erase(dotPosition, std::string::npos); - } - - std::string path = "js-bundles/" + entryName + "/"; - // android's asset manager does not work with paths that start with a dot - return dir == "." ? path : dir + "/" + path; -} - } // namespace react } // namespace facebook diff --git a/ReactCommon/cxxreact/RAMBundleRegistry.h b/ReactCommon/cxxreact/RAMBundleRegistry.h index d146be4477e..950379b83f4 100644 --- a/ReactCommon/cxxreact/RAMBundleRegistry.h +++ b/ReactCommon/cxxreact/RAMBundleRegistry.h @@ -28,7 +28,6 @@ public: JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId); virtual ~RAMBundleRegistry() {}; protected: - std::string jsBundlesDir(std::string entryFile); virtual std::unique_ptr bundleById(uint32_t index) const { throw std::runtime_error("Please, override this method in a subclass to support multiple RAM bundles."); }