From 4162d73ec04ea814df7ef6f6ce4d3261ee6b3608 Mon Sep 17 00:00:00 2001 From: Alex Dvornikov Date: Fri, 29 Sep 2017 14:42:24 -0700 Subject: [PATCH] Added Android support for loading multiple RAM bundles Differential Revision: D5901574 fbshipit-source-id: 395bae41e58505918d7ad20ac432eba3361361ea --- .../src/main/jni/react/jni/Android.mk | 1 + .../jni/react/jni/CatalystInstanceImpl.cpp | 5 +-- .../jni/react/jni/JniJSModulesUnbundle.cpp | 12 +++++-- .../main/jni/react/jni/JniJSModulesUnbundle.h | 6 +++- .../jni/react/jni/JniRAMBundleRegistry.cpp | 36 +++++++++++++++++++ .../main/jni/react/jni/JniRAMBundleRegistry.h | 21 +++++++++++ 6 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp create mode 100644 ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h diff --git a/ReactAndroid/src/main/jni/react/jni/Android.mk b/ReactAndroid/src/main/jni/react/jni/Android.mk index b132a41ff..6f4744a78 100644 --- a/ReactAndroid/src/main/jni/react/jni/Android.mk +++ b/ReactAndroid/src/main/jni/react/jni/Android.mk @@ -14,6 +14,7 @@ LOCAL_SRC_FILES := \ JSLoader.cpp \ JSLogging.cpp \ JniJSModulesUnbundle.cpp \ + JniRAMBundleRegistry.cpp \ MethodInvoker.cpp \ ModuleRegistryBuilder.cpp \ NativeArray.cpp \ diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index d5f9e0971..73571877a 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -23,6 +23,7 @@ #include "CxxModuleWrapper.h" #include "JavaScriptExecutorHolder.h" #include "JniJSModulesUnbundle.h" +#include "JniRAMBundleRegistry.h" #include "JNativeRunnable.h" #include "NativeArray.h" @@ -186,8 +187,8 @@ void CatalystInstanceImpl::jniLoadScriptFromAssets( auto manager = extractAssetManager(assetManager); auto script = loadScriptFromAssets(manager, sourceURL); if (JniJSModulesUnbundle::isUnbundle(manager, sourceURL)) { - auto bundle = folly::make_unique(manager, sourceURL); - auto registry = folly::make_unique(std::move(bundle)); + auto bundle = JniJSModulesUnbundle::fromEntryFile(manager, sourceURL); + auto registry = folly::make_unique(std::move(bundle), manager, sourceURL); instance_->loadRAMBundle( std::move(registry), std::move(script), diff --git a/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.cpp b/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.cpp index 20c71bc8c..fde1b40c8 100644 --- a/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.cpp @@ -10,6 +10,8 @@ #include #include +#include + using magic_number_t = uint32_t; const magic_number_t MAGIC_FILE_HEADER = 0xFB0BD1E5; const std::string MAGIC_FILE_NAME = "UNBUNDLE"; @@ -36,9 +38,15 @@ static asset_ptr openAsset( AAsset_close); } -JniJSModulesUnbundle::JniJSModulesUnbundle(AAssetManager *assetManager, const std::string& entryFile) : +std::unique_ptr JniJSModulesUnbundle::fromEntryFile( + AAssetManager *assetManager, + const std::string& entryFile) { + return folly::make_unique(assetManager, jsModulesDir(entryFile)); + } + +JniJSModulesUnbundle::JniJSModulesUnbundle(AAssetManager *assetManager, const std::string& moduleDirectory) : m_assetManager(assetManager), - m_moduleDirectory(jsModulesDir(entryFile)) {} + m_moduleDirectory(moduleDirectory) {} bool JniJSModulesUnbundle::isUnbundle( AAssetManager *assetManager, diff --git a/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.h b/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.h index daf88df51..8ca93b3ed 100644 --- a/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.h +++ b/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.h @@ -2,6 +2,8 @@ #pragma once +#include + #include #include @@ -14,10 +16,12 @@ class JniJSModulesUnbundle : public JSModulesUnbundle { */ public: JniJSModulesUnbundle() = default; - JniJSModulesUnbundle(AAssetManager *assetManager, const std::string& entryFile); + JniJSModulesUnbundle(AAssetManager *assetManager, const std::string& moduleDirectory); JniJSModulesUnbundle(JniJSModulesUnbundle&& other) = delete; JniJSModulesUnbundle& operator= (JSModulesUnbundle&& other) = delete; + static std::unique_ptr fromEntryFile(AAssetManager *assetManager, const std::string& entryFile); + static bool isUnbundle( AAssetManager *assetManager, const std::string& assetName); diff --git a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp new file mode 100644 index 000000000..17f38a81c --- /dev/null +++ b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.cpp @@ -0,0 +1,36 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#include "JniRAMBundleRegistry.h" + +#include + +#include +#include + +#include "JniJSModulesUnbundle.h" + +namespace facebook { +namespace react { + +static std::string jsBundlesDir(const std::string& entryFile) { + std::string dir = dirname(entryFile.c_str()); + std::string entryName = basename(entryFile.c_str()); + entryName.erase(entryName.find("."), 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; +} + +JniRAMBundleRegistry::JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& entryFile) : + RAMBundleRegistry(std::move(mainBundle)), + m_assetManager(assetManager), + m_baseDirectoryPath(jsBundlesDir(entryFile)) {} + +std::unique_ptr JniRAMBundleRegistry::bundleById(uint32_t index) const { + std::string bundlePathById = m_baseDirectoryPath + folly::to(index) + "/js-modules/"; + return folly::make_unique(m_assetManager, bundlePathById); +} + +} +} diff --git a/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h new file mode 100644 index 000000000..ce27f8635 --- /dev/null +++ b/ReactAndroid/src/main/jni/react/jni/JniRAMBundleRegistry.h @@ -0,0 +1,21 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#include +#include + +namespace facebook { +namespace react { + +class JniRAMBundleRegistry : public RAMBundleRegistry { +public: + JniRAMBundleRegistry(std::unique_ptr mainBundle, AAssetManager *assetManager, const std::string& entryFile); + +protected: + virtual std::unique_ptr bundleById(uint32_t index) const override; +private: + AAssetManager *m_assetManager = nullptr; + std::string m_baseDirectoryPath; +}; + +} +}