From 8ab159368743daaa5e22c662c7c1fe4c0b06fe8b Mon Sep 17 00:00:00 2001 From: yangzk Date: Mon, 30 Jun 2025 09:34:35 +0800 Subject: [PATCH 1/2] Revert "[draft][cannot merged] Description: load abc cannot mergegit add .git add .git add .git add .git add .git add .git add .git add . temp" This reverts commit 85f570ada7e61793cd85ee2389f525f3cd622bf0. Signed-off-by: yangzk Change-Id: I5ade5fc4cf52be9722359bef54817ec0f782186c --- .../native/runtime/js_module_reader.cpp | 66 +++++++------------ frameworks/native/runtime/js_module_reader.h | 11 ++-- .../ability_simulator/include/simulator.h | 2 +- .../runtime_test/js_module_reader_test.cpp | 6 +- 4 files changed, 31 insertions(+), 54 deletions(-) diff --git a/frameworks/native/runtime/js_module_reader.cpp b/frameworks/native/runtime/js_module_reader.cpp index 75f7a52b4af..ecb8023f739 100755 --- a/frameworks/native/runtime/js_module_reader.cpp +++ b/frameworks/native/runtime/js_module_reader.cpp @@ -44,59 +44,37 @@ JsModuleReader::JsModuleReader(const std::string& bundleName, const std::string& } } -std::shared_ptr JsModuleReader::GetExtractor( - const std::string& inputPath, bool isHybrid, std::string& errorMsg) const +bool JsModuleReader::operator()(const std::string& inputPath, uint8_t **buff, + size_t *buffSize, std::string& errorMsg) const { - auto realHapPath = GetAppPath(inputPath, SHARED_FILE_SUFFIX); + TAG_LOGD(AAFwkTag::JSRUNTIME, "called start: %{private}s", inputPath.c_str()); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (inputPath.empty() || buff == nullptr || buffSize == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid param"); + return false; + } + + auto realHapPath = GetAppHspPath(inputPath); if (realHapPath.empty()) { TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); - return nullptr; + return false; } + if (needFindPluginHsp_) { + // find plugin realHapPath = GetPluginHspPath(inputPath); if (realHapPath.empty()) { TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); - return nullptr; + return false; } needFindPluginHsp_ = true; } + bool newCreate = false; std::shared_ptr extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate); - if (extractor != nullptr) { - return extractor; - } - if (!isHybrid) { + if (extractor == nullptr) { errorMsg = "hap path error: " + realHapPath; TAG_LOGE(AAFwkTag::JSRUNTIME, "realHapPath %{private}s GetExtractor failed", realHapPath.c_str()); - return nullptr; - } - - realHapPath = GetAppPath(inputPath, ABILITY_FILE_SUFFIX); - if (realHapPath.empty()) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); - return nullptr; - } - extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate); - if (extractor == nullptr) { - errorMsg = "hap path error: " + inputPath; - TAG_LOGE(AAFwkTag::JSRUNTIME, "inputPath %{private}s GetExtractor failed", inputPath.c_str()); - return nullptr; - } - return extractor; -} - -bool JsModuleReader::operator()(const std::string& inputPath, bool isHybrid, - uint8_t **buff, size_t *buffSize, std::string& errorMsg) const -{ - TAG_LOGD(AAFwkTag::JSRUNTIME, "called start: %{private}s", inputPath.c_str()); - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - if (inputPath.empty() || buff == nullptr || buffSize == nullptr) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid param"); - return false; - } - - std::shared_ptr extractor = GetExtractor(inputPath, isHybrid, errorMsg); - if (extractor == nullptr) { return false; } @@ -153,17 +131,18 @@ std::string JsModuleReader::GetPluginHspPath(const std::string& inputPath) const return presetAppHapPath; } -std::string JsModuleReader::GetAppPath(const std::string& inputPath, const std::string& suffix) const +std::string JsModuleReader::GetAppHspPath(const std::string& inputPath) const { if (isFormRender_) { - return GetFormAppPath(inputPath, suffix); + return GetFormAppHspPath(inputPath); } - return GetCommonAppPath(inputPath, suffix); + return GetCommonAppHspPath(inputPath); } -std::string JsModuleReader::GetFormAppPath(const std::string& inputPath, const std::string& suffix) const +std::string JsModuleReader::GetFormAppHspPath(const std::string& inputPath) const { std::string realHapPath; + std::string suffix = std::string(SHARED_FILE_SUFFIX); realHapPath.append("/data/bundles/") .append(bundleName_).append("/") .append(GetModuleName(inputPath)) @@ -184,8 +163,9 @@ std::string JsModuleReader::GetModuleName(const std::string& inputPath) const return inputPath.substr(inputPath.find_last_of("/") + 1); } -std::string JsModuleReader::GetCommonAppPath(const std::string& inputPath, const std::string& suffix) const +std::string JsModuleReader::GetCommonAppHspPath(const std::string& inputPath) const { + std::string suffix = std::string(SHARED_FILE_SUFFIX); std::string realHapPath = GetPresetAppHapPath(inputPath, bundleName_); if ((realHapPath.find(ABS_DATA_CODE_PATH) == 0) || (realHapPath == inputPath)) { realHapPath = std::string(ABS_CODE_PATH) + inputPath + suffix; diff --git a/frameworks/native/runtime/js_module_reader.h b/frameworks/native/runtime/js_module_reader.h index 78170d7d54c..1777266c385 100755 --- a/frameworks/native/runtime/js_module_reader.h +++ b/frameworks/native/runtime/js_module_reader.h @@ -34,7 +34,6 @@ public: static constexpr char MERGE_ABC_PATH[] = "ets/modules.abc"; static constexpr char SYS_ABS_CODE_PATH[] = "/system/app/appServiceFwk/"; static constexpr char SHARED_FILE_SUFFIX[] = ".hsp"; - static constexpr char ABILITY_FILE_SUFFIX[] = ".hap"; JsModuleReader(const std::string& bundleName, const std::string& hapPath, bool isFormRender = false); ~JsModuleReader() = default; @@ -43,18 +42,16 @@ public: JsModuleReader& operator=(const JsModuleReader&) = default; JsModuleReader& operator=(JsModuleReader&&) = default; - bool operator()(const std::string& inputPath, bool isHybrid, - uint8_t **buff, size_t *buffSize, std::string& errorMsg) const; + bool operator()(const std::string& inputPath, uint8_t **buff, size_t *buffSize, std::string& errorMsg) const; static std::string GetPresetAppHapPath(const std::string& inputPath, const std::string& bundleName); static void GetHapPathList(const std::string &bundleName, std::vector &hapList); private: - std::string GetAppPath(const std::string& inputPath, const std::string& suffix) const; - std::string GetCommonAppPath(const std::string& inputPath, const std::string& suffix) const; - std::string GetFormAppPath(const std::string& inputPath, const std::string& suffix) const; + std::string GetAppHspPath(const std::string& inputPath) const; + std::string GetCommonAppHspPath(const std::string& inputPath) const; + std::string GetFormAppHspPath(const std::string& inputPath) const; std::string GetModuleName(const std::string& inputPath) const; std::string GetPluginHspPath(const std::string& inputPath) const; - std::shared_ptr GetExtractor(const std::string& inputPath, bool isHybrid, std::string& errorMsg) const; static std::string GetOtherHspPath(const std::string& bundleName, const std::string& moduleName, const std::string& inputPath); diff --git a/frameworks/simulator/ability_simulator/include/simulator.h b/frameworks/simulator/ability_simulator/include/simulator.h index b85ea863e5f..ffd81e5bf32 100644 --- a/frameworks/simulator/ability_simulator/include/simulator.h +++ b/frameworks/simulator/ability_simulator/include/simulator.h @@ -36,7 +36,7 @@ public: using TerminateCallback = std::function; using FormUpdateCallback = std::function; using ResolveBufferTrackerCallback = std::function; + const std::string&, uint8_t **, size_t *, std::string& errorMsg)>; /** * Create a simulator instance. diff --git a/test/unittest/runtime_test/js_module_reader_test.cpp b/test/unittest/runtime_test/js_module_reader_test.cpp index d1270af25ec..6c4e354fa71 100644 --- a/test/unittest/runtime_test/js_module_reader_test.cpp +++ b/test/unittest/runtime_test/js_module_reader_test.cpp @@ -61,7 +61,7 @@ HWTEST_F(JsModuleReaderTest, JsModuleReaderTest_0100, TestSize.Level2) uint8_t *buff = nullptr; size_t buffSize = 0; std::string errorMsg = ""; - auto result = jsModuleReader("", false, &buff, &buffSize, errorMsg); + auto result = jsModuleReader("", &buff, &buffSize, errorMsg); EXPECT_EQ(result, false); } @@ -77,7 +77,7 @@ HWTEST_F(JsModuleReaderTest, JsModuleReaderTest_0200, TestSize.Level2) uint8_t *buff = nullptr; size_t buffSize = 0; std::string errorMsg = ""; - auto result = jsModuleReader("bundleName/moduleName", false, &buff, &buffSize, errorMsg); + auto result = jsModuleReader("bundleName/moduleName", &buff, &buffSize, errorMsg); EXPECT_EQ(result, false); } @@ -113,7 +113,7 @@ EXPECT_TRUE(hapPath.empty()); HWTEST_F(JsModuleReaderTest, GetFormAppHspPathTest_0100, TestSize.Level2) { JsModuleReader jsModuleReader("JsModuleReader", ""); - auto realHapPath = jsModuleReader.GetFormAppPath("inputPath", ".hsp"); + auto realHapPath = jsModuleReader.GetFormAppHspPath("inputPath"); EXPECT_EQ(realHapPath, "/data/bundles/JsModuleReader/inputPath.hsp"); } -- Gitee From 71ab0548a75a4a4cea6baa3989379f9c6ebf0583 Mon Sep 17 00:00:00 2001 From: yangzk Date: Fri, 6 Jun 2025 10:51:50 +0800 Subject: [PATCH 2/2] Description: add hybrid js module reader IssueNo: Sig: SIG_ApplicationFramework Feature or Bugfix: Bugfix Binary Source: No Signed-off-by: yangzk Change-Id: Ibde52b60148e239336569bd24689e94a4d67a5a0 --- frameworks/native/runtime/ets_runtime.cpp | 8 +- .../runtime/hybrid_js_module_reader.cpp | 273 ++++++++++++++++++ .../native/runtime/hybrid_js_module_reader.h | 66 +++++ interfaces/inner_api/runtime/BUILD.gn | 1 + test/unittest/runtime_test/BUILD.gn | 26 ++ .../hybrid_js_module_reader_test.cpp | 104 +++++++ 6 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 frameworks/native/runtime/hybrid_js_module_reader.cpp create mode 100644 frameworks/native/runtime/hybrid_js_module_reader.h create mode 100644 test/unittest/runtime_test/hybrid_js_module_reader_test.cpp diff --git a/frameworks/native/runtime/ets_runtime.cpp b/frameworks/native/runtime/ets_runtime.cpp index f32bb200bbf..431177bfe99 100644 --- a/frameworks/native/runtime/ets_runtime.cpp +++ b/frameworks/native/runtime/ets_runtime.cpp @@ -27,6 +27,7 @@ #include "ets_interface.h" #include "file_path_utils.h" #include "hilog_tag_wrapper.h" +#include "hybrid_js_module_reader.h" #ifdef SUPPORT_SCREEN #include "ace_forward_compatibility.h" @@ -228,7 +229,6 @@ std::unique_ptr ETSRuntime::Create(const Options &options, std::uniq return std::unique_ptr(); } EntryPathManager::GetInstance().Init(); - return instance; } @@ -272,6 +272,12 @@ bool ETSRuntime::Initialize(const Options &options, std::unique_ptr & return false; } + if (jsRuntime_ != nullptr) { + auto vm = static_cast(jsRuntime_.get())->GetEcmaVm(); + panda::JSNApi::SetHostResolveBufferTrackerForHybridApp( + vm, HybridJsModuleReader(options.bundleName, options.hapPath, options.isUnique)); + } + apiTargetVersion_ = options.apiTargetVersion; TAG_LOGD(AAFwkTag::ETSRUNTIME, "Initialize: %{public}d", apiTargetVersion_); return true; diff --git a/frameworks/native/runtime/hybrid_js_module_reader.cpp b/frameworks/native/runtime/hybrid_js_module_reader.cpp new file mode 100644 index 00000000000..f1bc295596e --- /dev/null +++ b/frameworks/native/runtime/hybrid_js_module_reader.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hybrid_js_module_reader.h" + +#include +#include "bundle_info.h" +#include "bundle_mgr_helper.h" +#include "bundle_mgr_proxy.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "iservice_registry.h" +#include "js_runtime_utils.h" +#include "singleton.h" + +using namespace OHOS::AbilityBase; + +namespace OHOS { +namespace AbilityRuntime { +bool HybridJsModuleReader::needFindPluginHsp_ = true; + +HybridJsModuleReader::HybridJsModuleReader(const std::string& bundleName, const std::string& hapPath, bool isFormRender) + : JsModuleSearcher(bundleName), isFormRender_(isFormRender) +{ + if (!hapPath.empty() && hapPath.find(std::string(ABS_DATA_CODE_PATH)) != 0) { + isSystemPath_ = true; + } else { + isSystemPath_ = false; + } +} + +std::shared_ptr HybridJsModuleReader::GetExtractor( + const std::string& inputPath, std::string& errorMsg) const +{ + auto realHapPath = GetAppPath(inputPath, SHARED_FILE_SUFFIX); + if (realHapPath.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); + return nullptr; + } + if (needFindPluginHsp_) { + realHapPath = GetPluginHspPath(inputPath); + if (realHapPath.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); + return nullptr; + } + needFindPluginHsp_ = true; + } + bool newCreate = false; + std::shared_ptr extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate); + if (extractor != nullptr) { + return extractor; + } + + realHapPath = GetAppPath(inputPath, ABILITY_FILE_SUFFIX); + if (realHapPath.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty realHapPath"); + return nullptr; + } + extractor = ExtractorUtil::GetExtractor(realHapPath, newCreate); + if (extractor == nullptr) { + errorMsg = "hap path error: " + inputPath; + TAG_LOGE(AAFwkTag::JSRUNTIME, "inputPath %{private}s GetExtractor failed", inputPath.c_str()); + return nullptr; + } + return extractor; +} + +bool HybridJsModuleReader::operator()(const std::string& inputPath, + uint8_t **buff, size_t *buffSize, std::string& errorMsg) const +{ + TAG_LOGD(AAFwkTag::JSRUNTIME, "called start: %{private}s", inputPath.c_str()); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (inputPath.empty() || buff == nullptr || buffSize == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid param"); + return false; + } + + std::shared_ptr extractor = GetExtractor(inputPath, errorMsg); + if (extractor == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "failed to get extractor %{private}s", inputPath.c_str()); + return false; + } + + auto data = extractor->GetSafeData(MERGE_ABC_PATH); + if (!data) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null data"); + return false; + } + + *buff = data->GetDataPtr(); + *buffSize = data->GetDataLen(); + return true; +} + +std::string HybridJsModuleReader::GetPluginHspPath(const std::string& inputPath) const +{ + std::string presetAppHapPath = ""; + auto bundleMgrHelper = DelayedSingleton::GetInstance(); + if (bundleMgrHelper == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper"); + return presetAppHapPath; + } + std::string moduleName = inputPath.substr(inputPath.find_last_of("/") + 1); + std::string tmpPath = inputPath.substr(inputPath.find_first_of("/") + 1); + const std::string sharedBundleName = tmpPath.substr(0, tmpPath.find_first_of("/")); + TAG_LOGI(AAFwkTag::JSRUNTIME, "moduleName: %{public}s, sharedBundleName: %{public}s", + moduleName.c_str(), sharedBundleName.c_str()); + if (moduleName.empty() || sharedBundleName.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty moduleName"); + return presetAppHapPath; + } + + std::vector pluginBundleInfos; + if (bundleMgrHelper->GetPluginInfosForSelf(pluginBundleInfos) != ERR_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginInfosForSelf failed"); + return presetAppHapPath; + } + + for (auto &pluginBundleInfo : pluginBundleInfos) { + for (auto &pluginModuleInfo : pluginBundleInfo.pluginModuleInfos) { + if (moduleName == pluginModuleInfo.moduleName + && sharedBundleName == pluginBundleInfo.pluginBundleName) { + presetAppHapPath = pluginModuleInfo.hapPath; + TAG_LOGD(AAFwkTag::JSRUNTIME, "presetAppHapPath %{public}s", presetAppHapPath.c_str()); + std::regex pattern(std::string(ABS_DATA_CODE_PATH) + bundleName_ + "/"); + presetAppHapPath = std::regex_replace( + presetAppHapPath, pattern, std::string(ABS_CODE_PATH) + std::string(BUNDLE)); + TAG_LOGD(AAFwkTag::JSRUNTIME, "presetAppHapPath %{public}s", presetAppHapPath.c_str()); + return presetAppHapPath; + } + } + } + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetPluginHspPath failed"); + return presetAppHapPath; +} + +std::string HybridJsModuleReader::GetAppPath(const std::string& inputPath, const std::string& suffix) const +{ + if (isFormRender_) { + return GetFormAppPath(inputPath, suffix); + } + return GetCommonAppPath(inputPath, suffix); +} + +std::string HybridJsModuleReader::GetFormAppPath(const std::string& inputPath, const std::string& suffix) const +{ + std::string realHapPath; + realHapPath.append("/data/bundles/") + .append(bundleName_).append("/") + .append(GetModuleName(inputPath)) + .append(SHARED_FILE_SUFFIX); + + TAG_LOGI(AAFwkTag::JSRUNTIME, "realHapPath: %{private}s", realHapPath.c_str()); + if (realHapPath.empty() || + realHapPath.length() < suffix.length() || + realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "obtain realHapPath failed"); + return realHapPath; + } + return realHapPath; +} + +std::string HybridJsModuleReader::GetModuleName(const std::string& inputPath) const +{ + return inputPath.substr(inputPath.find_last_of("/") + 1); +} + +std::string HybridJsModuleReader::GetCommonAppPath(const std::string& inputPath, const std::string& suffix) const +{ + std::string realHapPath = GetPresetAppHapPath(inputPath, bundleName_); + if ((realHapPath.find(ABS_DATA_CODE_PATH) == 0) || (realHapPath == inputPath)) { + realHapPath = std::string(ABS_CODE_PATH) + inputPath + suffix; + } + + TAG_LOGD(AAFwkTag::JSRUNTIME, "realHapPath: %{private}s", realHapPath.c_str()); + if (realHapPath.empty() || + realHapPath.length() < suffix.length() || + realHapPath.compare(realHapPath.length() - suffix.length(), suffix.length(), suffix) != 0) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "obtain realHapPath failed"); + return realHapPath; + } + return realHapPath; +} + +std::string HybridJsModuleReader::GetOtherHspPath(const std::string& bundleName, const std::string& moduleName, + const std::string& inputPath) +{ + std::string presetAppHapPath = inputPath; + + auto bundleMgrHelper = DelayedSingleton::GetInstance(); + if (bundleMgrHelper == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper"); + return presetAppHapPath; + } + + std::vector baseSharedBundleInfos; + if (bundleMgrHelper->GetBaseSharedBundleInfos(bundleName, baseSharedBundleInfos) != 0) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetBaseSharedBundleInfos failed"); + return presetAppHapPath; + } + std::string tmpPath = inputPath.substr(inputPath.find_first_of("/") + 1); + const std::string sharedBundleName = tmpPath.substr(0, tmpPath.find_first_of("/")); + for (const auto &info : baseSharedBundleInfos) { + if ((info.bundleName == sharedBundleName) && (info.moduleName == moduleName)) { + presetAppHapPath = info.hapPath; + needFindPluginHsp_ = false; + break; + } + } + AppExecFwk::BundleInfo bundleInfo; + int32_t ret = bundleMgrHelper->GetDependentBundleInfo(sharedBundleName, bundleInfo, + AppExecFwk::GetDependentBundleInfoFlag::GET_APP_SERVICE_HSP_BUNDLE_INFO); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetDependentBundleInfo failed"); + return presetAppHapPath; + } + for (const auto &info : bundleInfo.hapModuleInfos) { + if (info.moduleName == moduleName) { + presetAppHapPath = info.hapPath; + needFindPluginHsp_ = false; + break; + } + } + return presetAppHapPath; +} + +std::string HybridJsModuleReader::GetPresetAppHapPath(const std::string& inputPath, const std::string& bundleName) +{ + std::string presetAppHapPath = inputPath; + std::string moduleName = inputPath.substr(inputPath.find_last_of("/") + 1); + if (moduleName.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "empty moduleName"); + return presetAppHapPath; + } + auto bundleMgrHelper = DelayedSingleton::GetInstance(); + if (bundleMgrHelper == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null bundleMgrHelper"); + return presetAppHapPath; + } + if (inputPath.find_first_of("/") == inputPath.find_last_of("/")) { + AppExecFwk::BundleInfo bundleInfo; + auto getInfoResult = bundleMgrHelper->GetBundleInfoForSelf(static_cast(AppExecFwk::GetBundleInfoFlag:: + GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo); + if (getInfoResult != 0 || bundleInfo.hapModuleInfos.empty()) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetBundleInfoForSelf failed"); + return presetAppHapPath; + } + for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { + if (hapModuleInfo.moduleName == moduleName) { + presetAppHapPath = hapModuleInfo.hapPath; + needFindPluginHsp_ = false; + break; + } + } + } else { + presetAppHapPath = GetOtherHspPath(bundleName, moduleName, presetAppHapPath); + } + return presetAppHapPath; +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/runtime/hybrid_js_module_reader.h b/frameworks/native/runtime/hybrid_js_module_reader.h new file mode 100644 index 00000000000..0267dd42641 --- /dev/null +++ b/frameworks/native/runtime/hybrid_js_module_reader.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_HYBRID_JS_MODULE_READER_H +#define OHOS_ABILITY_RUNTIME_HYBRID_JS_MODULE_READER_H + +#include +#include + +#include "js_module_searcher.h" +#include "extractor.h" + +using Extractor = OHOS::AbilityBase::Extractor; + +namespace OHOS { +namespace AbilityRuntime { +class HybridJsModuleReader final : private JsModuleSearcher { +public: + static constexpr char ABS_CODE_PATH[] = "/data/storage/el1/"; + static constexpr char ABS_DATA_CODE_PATH[] = "/data/app/el1/bundle/public/"; + static constexpr char BUNDLE[] = "bundle/"; + static constexpr char MERGE_ABC_PATH[] = "ets/modules.abc"; + static constexpr char SYS_ABS_CODE_PATH[] = "/system/app/appServiceFwk/"; + static constexpr char SHARED_FILE_SUFFIX[] = ".hsp"; + static constexpr char ABILITY_FILE_SUFFIX[] = ".hap"; + HybridJsModuleReader(const std::string& bundleName, const std::string& hapPath, bool isFormRender = false); + ~HybridJsModuleReader() = default; + + HybridJsModuleReader(const HybridJsModuleReader&) = default; + HybridJsModuleReader(HybridJsModuleReader&&) = default; + HybridJsModuleReader& operator=(const HybridJsModuleReader&) = default; + HybridJsModuleReader& operator=(HybridJsModuleReader&&) = default; + + bool operator()(const std::string& inputPath, uint8_t **buff, size_t *buffSize, std::string& errorMsg) const; + static std::string GetPresetAppHapPath(const std::string& inputPath, const std::string& bundleName); + +private: + std::string GetAppPath(const std::string& inputPath, const std::string& suffix) const; + std::string GetCommonAppPath(const std::string& inputPath, const std::string& suffix) const; + std::string GetFormAppPath(const std::string& inputPath, const std::string& suffix) const; + std::string GetModuleName(const std::string& inputPath) const; + std::string GetPluginHspPath(const std::string& inputPath) const; + std::shared_ptr GetExtractor(const std::string& inputPath, std::string& errorMsg) const; + static std::string GetOtherHspPath(const std::string& bundleName, const std::string& moduleName, + const std::string& inputPath); + + bool isSystemPath_ = false; + bool isFormRender_ = false; + static bool needFindPluginHsp_; +}; +} // namespace AbilityRuntime +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_HYBRID_JS_MODULE_READER_H diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index 5fe4bec9b94..b86ef2879df 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -66,6 +66,7 @@ ohos_shared_library("runtime") { "${ability_runtime_native_path}/runtime/ets_data_struct_converter.cpp", "${ability_runtime_native_path}/runtime/ets_runtime.cpp", "${ability_runtime_native_path}/runtime/hdc_register.cpp", + "${ability_runtime_native_path}/runtime/hybrid_js_module_reader.cpp", "${ability_runtime_native_path}/runtime/js_app_process_state.cpp", "${ability_runtime_native_path}/runtime/js_data_struct_converter.cpp", "${ability_runtime_native_path}/runtime/js_error_utils.cpp", diff --git a/test/unittest/runtime_test/BUILD.gn b/test/unittest/runtime_test/BUILD.gn index 04ea956914b..99d92adbb8c 100644 --- a/test/unittest/runtime_test/BUILD.gn +++ b/test/unittest/runtime_test/BUILD.gn @@ -65,6 +65,31 @@ ohos_unittest("runtime_test") { ] } +ohos_unittest("hybrid_js_module_reader_test") { + module_out_path = module_output_path + + include_dirs = [ + "${ability_runtime_native_path}/runtime", + "${ability_runtime_native_path}/runtime/utils/include", + ] + + sources = [ + # add mock file + "hybrid_js_module_reader_test.cpp", + ] + + configs = [ "${ability_runtime_services_path}/abilitymgr:abilityms_config" ] + deps = [] + + external_deps = [ + "ability_base:extractortool", + "ability_runtime:runtime", + "c_utils:utils", + "zlib:libz", + "zlib:shared_libz", + ] +} + ohos_unittest("js_runtime_test") { module_out_path = module_output_path sanitize = { @@ -289,6 +314,7 @@ group("unittest") { deps = [ ":hdc_register_test", ":ets_runtime_test", + ":hybrid_js_module_reader_test", ":js_runtime_first_test", ":js_runtime_test", ":js_worker_test", diff --git a/test/unittest/runtime_test/hybrid_js_module_reader_test.cpp b/test/unittest/runtime_test/hybrid_js_module_reader_test.cpp new file mode 100644 index 00000000000..1bbefa014c9 --- /dev/null +++ b/test/unittest/runtime_test/hybrid_js_module_reader_test.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "hybrid_js_module_reader.h" +#include "extractor.h" + +using namespace testing; +using namespace testing::ext; +using HybridJsModuleReader = OHOS::AbilityRuntime::HybridJsModuleReader; +using Extractor = OHOS::AbilityBase::Extractor; + +namespace OHOS { +namespace AAFwk { +class HybridJsModuleReaderTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +void HybridJsModuleReaderTest::SetUpTestCase() +{} + +void HybridJsModuleReaderTest::TearDownTestCase() +{} + +void HybridJsModuleReaderTest::SetUp() +{} + +void HybridJsModuleReaderTest::TearDown() +{} + +/** + * @tc.name: HybridJsModuleReaderTest_0100 + * @tc.desc: HybridJsModuleReaderTest Test + * @tc.type: FUNC + * @tc.require: issueI581SE + */ +HWTEST_F(HybridJsModuleReaderTest, HybridJsModuleReaderTest_0100, TestSize.Level0) +{ + HybridJsModuleReader HybridJsModuleReader("HybridJsModuleReader", ""); + uint8_t *buff = nullptr; + size_t buffSize = 0; + std::string errorMsg = ""; + auto result = HybridJsModuleReader("", &buff, &buffSize, errorMsg); + EXPECT_EQ(result, false); +} + +/** + * @tc.name: HybridJsModuleReaderTest_0200 + * @tc.desc: HybridJsModuleReaderTest Test + * @tc.type: FUNC + * @tc.require: issueI581RO + */ +HWTEST_F(HybridJsModuleReaderTest, HybridJsModuleReaderTest_0200, TestSize.Level0) +{ + HybridJsModuleReader HybridJsModuleReader("HybridJsModuleReader", ""); + uint8_t *buff = nullptr; + size_t buffSize = 0; + std::string errorMsg = ""; + auto result = HybridJsModuleReader("bundleName/moduleName", &buff, &buffSize, errorMsg); + EXPECT_EQ(result, false); +} + +/** + * @tc.name: GetPresetAppHapPathTest_0100 + * @tc.desc: GetPresetAppHapPath Test + * @tc.type: FUNC + */ +HWTEST_F(HybridJsModuleReaderTest, GetPresetAppHapPathTest_0100, TestSize.Level0) +{ + HybridJsModuleReader HybridJsModuleReader("HybridJsModuleReader", ""); + std::string hapPath = HybridJsModuleReader.GetPresetAppHapPath("", ""); + EXPECT_TRUE(hapPath.empty()); +} + +/** + * @tc.name: GetPresetAppHapPathTest_0200 + * @tc.desc: GetPresetAppHapPath Test + * @tc.type: FUNC + */ +HWTEST_F(HybridJsModuleReaderTest, GetPresetAppHapPathTest_0200, TestSize.Level0) +{ + HybridJsModuleReader HybridJsModuleReader("HybridJsModuleReader", "/data/storage/el1/test.hsp"); + std::string hapPath = HybridJsModuleReader.GetPresetAppHapPath("", ""); + EXPECT_TRUE(hapPath.empty()); +} +} // namespace AAFwk +} // namespace OHOS -- Gitee