From cc40eb0f6cd147229ce41b1964d853def0cd3efe Mon Sep 17 00:00:00 2001 From: y00620503 Date: Sat, 5 Jul 2025 18:35:14 +0800 Subject: [PATCH 1/2] extension api 1.2 control Signed-off-by: y00620503 --- .../etc/extension_blocklist_config.json | 3 + .../ability/native/extension_config_mgr.cpp | 106 +++++++++- frameworks/native/appkit/app/main_thread.cpp | 2 +- frameworks/native/runtime/ets_runtime.cpp | 6 + .../inner_api/runtime/include/cj_runtime.h | 2 + .../inner_api/runtime/include/ets_runtime.h | 1 + .../inner_api/runtime/include/js_runtime.h | 1 + .../inner_api/runtime/include/runtime.h | 1 + .../ability/native/extension_config_mgr.h | 34 +++- .../kits/native/appkit/app/main_thread.h | 2 +- .../mock_runtime.h | 2 +- .../extension_config_mgr_test.cpp | 190 ++++++++++++++++++ .../insight_intent/mock/mock_runtime.h | 1 + 13 files changed, 344 insertions(+), 7 deletions(-) diff --git a/frameworks/native/ability/native/etc/extension_blocklist_config.json b/frameworks/native/ability/native/etc/extension_blocklist_config.json index 6c331eeb291..0f7fd479f3f 100644 --- a/frameworks/native/ability/native/etc/extension_blocklist_config.json +++ b/frameworks/native/ability/native/etc/extension_blocklist_config.json @@ -545,5 +545,8 @@ "AppServiceExtension": [ "window" ] + }, + "replaceModuleList": { + "bundle": "bundle.bundle" } } diff --git a/frameworks/native/ability/native/extension_config_mgr.cpp b/frameworks/native/ability/native/extension_config_mgr.cpp index c430ca741df..df4c956db9f 100644 --- a/frameworks/native/ability/native/extension_config_mgr.cpp +++ b/frameworks/native/ability/native/extension_config_mgr.cpp @@ -15,6 +15,7 @@ #include "extension_config_mgr.h" +#include #include #include "app_module_checker.h" @@ -27,6 +28,26 @@ namespace { constexpr char EXTENSION_BLOCKLIST_FILE_PATH[] = "/system/etc/extension_blocklist_config.json"; } +void ExtensionConfigMgr::ParseReplaceModuleLists(const cJSON *extensionConfig) +{ + cJSON *replaceModuleItem = cJSON_GetObjectItem(extensionConfig, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST); + if (replaceModuleItem == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "extension config file have no replace module list node"); + return; + } + cJSON *childItem = replaceModuleItem->child; + while (childItem != nullptr) { + if (!cJSON_IsString(childItem)) { + continue; + } + std::string key = childItem->string == nullptr ? "" : childItem->string; + std::string value = childItem->valuestring; + replaceModuleListConfig_.emplace(key, value); + + childItem = childItem->next; + } +} + void ExtensionConfigMgr::Init() { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -75,6 +96,7 @@ void ExtensionConfigMgr::Init() childItem = childItem->next; } + ParseReplaceModuleLists(extensionConfig); cJSON_Delete(extensionConfig); TAG_LOGD(AAFwkTag::EXT, "Init end"); } @@ -97,8 +119,86 @@ void ExtensionConfigMgr::UpdateRuntimeModuleChecker(const std::unique_ptr(extensionType_, extensionBlocklist_); - runtime->SetModuleLoadChecker(moduleChecker); - extensionBlocklist_.clear(); + GenerateExtensionEtsBlocklists(); + if (runtime->GetLanguage() == AbilityRuntime::Runtime::Language::ETS) { + TAG_LOGD(AAFwkTag::EXT, "ets runtime"); + SetExtensionEtsCheckCallback(runtime); + } else { + TAG_LOGD(AAFwkTag::EXT, "not ets runtime"); + auto moduleChecker = std::make_shared(extensionType_, extensionBlocklist_); + runtime->SetModuleLoadChecker(moduleChecker); + extensionBlocklist_.clear(); + } +} + +void ExtensionConfigMgr::GenerateExtensionEtsBlocklists() +{ + if (!extensionEtsBlocklist_.empty()) { + TAG_LOGD(AAFwkTag::EXT, "extension ets block list not empty."); + return; + } + auto iter = extensionBlocklist_.find(extensionType_); + if (iter == extensionBlocklist_.end()) { + TAG_LOGD(AAFwkTag::EXT, "null extension block, extensionType: %{public}d.", extensionType_); + return; + } + for (const auto& module: iter->second) { + auto replaceIter = replaceModuleListConfig_.find(module); + if (replaceIter == replaceModuleListConfig_.end()) { + std::string lowermodule; + lowermodule.reserve(module.size()); + std::transform(module.cbegin(), module.cend(), std::back_inserter(lowermodule), + [](unsigned char c) { return std::tolower(c); }); + extensionEtsBlocklist_.emplace(std::move(lowermodule)); + } else { + std::string lowerReplaceModule; + lowerReplaceModule.reserve(replaceIter->second.size()); + std::transform(replaceIter->second.cbegin(), replaceIter->second.cend(), + std::back_inserter(lowerReplaceModule), [](unsigned char c) { return std::tolower(c); }); + extensionEtsBlocklist_.emplace(std::move(lowerReplaceModule)); + } + } +} + +bool ExtensionConfigMgr::CheckEtsModuleLoadable(const std::string &className) +{ + std::string classNameAfterRemovePreFix; + if (className.length() >= ExtensionConfigItem::ITEM_LENGTH_OHOSPREFIX && + (className.compare(0, ExtensionConfigItem::ITEM_LENGTH_OHOSPREFIX, ExtensionConfigItem::ITEM_NAME_OHOSPREFIX) + == 0)) { + classNameAfterRemovePreFix = className.substr(ExtensionConfigItem::ITEM_LENGTH_OHOSPREFIX); + } else if (className.length() >= ExtensionConfigItem::ITEM_LENGTH_HMSPREFIX && + (className.compare(0, ExtensionConfigItem::ITEM_LENGTH_HMSPREFIX, ExtensionConfigItem::ITEM_NAME_HMSPREFIX) + == 0)) { + classNameAfterRemovePreFix = className.substr(ExtensionConfigItem::ITEM_LENGTH_HMSPREFIX); + } else { + classNameAfterRemovePreFix = className; + } + std::string lowerClassName; + lowerClassName.reserve(className.size()); + std::transform(className.cbegin(), className.cend(), std::back_inserter(lowerClassName), + [](unsigned char c) { return std::tolower(c); }); + TAG_LOGD(AAFwkTag::EXT, "extensionType: %{public}d, className is %{public}s.", extensionType_, className.c_str()); + for (const auto& blockClassName: extensionEtsBlocklist_) { + if (lowerClassName.compare(0, blockClassName.length(), blockClassName) == 0) { + TAG_LOGD(AAFwkTag::EXT, "className is %{public}s in blocklist.", className.c_str()); + return false; + } + } + TAG_LOGD(AAFwkTag::EXT, "className is %{public}s in not blocklist.", className.c_str()); + return true; +} + +void ExtensionConfigMgr::SetExtensionEtsCheckCallback(const std::unique_ptr &runtime) +{ + auto callback = [extensionConfigMgrWeak = weak_from_this()](const std::string &className) -> bool { + auto extensionConfigMgr = extensionConfigMgrWeak.lock(); + if (extensionConfigMgr == nullptr) { + TAG_LOGD(AAFwkTag::EXT, "null extensionConfigMgr"); + return false; + } + return extensionConfigMgr->CheckEtsModuleLoadable(className); + }; + runtime->SetExtensionApiCheckCallback(callback); } } \ No newline at end of file diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index f5b40c21ced..671c9b7d6f3 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -2838,7 +2838,7 @@ void MainThread::Init(const std::shared_ptr &runner) TAG_LOGD(AAFwkTag::APPKIT, "Start"); mainHandler_ = std::make_shared(runner, this); watchdog_ = std::make_shared(); - extensionConfigMgr_ = std::make_unique(); + extensionConfigMgr_ = std::make_shared(); wptr weak = this; auto task = [weak]() { auto appThread = weak.promote(); diff --git a/frameworks/native/runtime/ets_runtime.cpp b/frameworks/native/runtime/ets_runtime.cpp index f32bb200bbf..281eaa9fa48 100644 --- a/frameworks/native/runtime/ets_runtime.cpp +++ b/frameworks/native/runtime/ets_runtime.cpp @@ -258,6 +258,12 @@ void ETSRuntime::SetAppLibPath(const AppLibPathMap &appLibPaths) g_etsEnvFuncs->InitETSSysNS(ETS_SYSLIB_PATH); } +void ETSRuntime::SetExtensionApiCheckCallback(const std::function &cb) +{ + TAG_LOGD(AAFwkTag::ETSRUNTIME, "called"); + // ark::ets::EtsNamespaceManager::SetExtensionApiCheckCallback(std::move(cb)); +} + bool ETSRuntime::Initialize(const Options &options, std::unique_ptr &jsRuntime) { TAG_LOGD(AAFwkTag::ETSRUNTIME, "Initialize called"); diff --git a/interfaces/inner_api/runtime/include/cj_runtime.h b/interfaces/inner_api/runtime/include/cj_runtime.h index 07ecd75405b..b32f29953d6 100644 --- a/interfaces/inner_api/runtime/include/cj_runtime.h +++ b/interfaces/inner_api/runtime/include/cj_runtime.h @@ -16,6 +16,7 @@ #ifndef OHOS_ABILITY_RUNTIME_CJ_RUNTIME_H #define OHOS_ABILITY_RUNTIME_CJ_RUNTIME_H +#include #include #include #include @@ -63,6 +64,7 @@ public: bool UnLoadRepairPatch(const std::string& patchFile) override { return false; } void RegisterQuickFixQueryFunc(const std::map& moduleAndPath) override {}; void StartProfiler(const DebugOption dOption) override; + void SetExtensionApiCheckCallback(const std::function &cb) override {} void SetModuleLoadChecker(const std::shared_ptr moduleCheckerDelegate) const override {} void SetDeviceDisconnectCallback(const std::function &cb) override {}; bool IsAppLibLoaded() const { return appLibLoaded_; } diff --git a/interfaces/inner_api/runtime/include/ets_runtime.h b/interfaces/inner_api/runtime/include/ets_runtime.h index 2b332eee8a3..66513d603ee 100644 --- a/interfaces/inner_api/runtime/include/ets_runtime.h +++ b/interfaces/inner_api/runtime/include/ets_runtime.h @@ -71,6 +71,7 @@ public: bool UnLoadRepairPatch(const std::string &patchFile) override { return false; } void RegisterQuickFixQueryFunc(const std::map &moduleAndPath) override {}; void StartProfiler(const DebugOption debugOption) override {}; + void SetExtensionApiCheckCallback(const std::function &cb) override; void SetModuleLoadChecker(const std::shared_ptr moduleCheckerDelegate) const override {} void SetDeviceDisconnectCallback(const std::function &cb) override {}; void DestroyHeapProfiler() override {}; diff --git a/interfaces/inner_api/runtime/include/js_runtime.h b/interfaces/inner_api/runtime/include/js_runtime.h index 7e514e2ee6a..a48fa12e352 100644 --- a/interfaces/inner_api/runtime/include/js_runtime.h +++ b/interfaces/inner_api/runtime/include/js_runtime.h @@ -136,6 +136,7 @@ public: void FreeNativeReference(std::unique_ptr reference); void FreeNativeReference(std::shared_ptr&& reference); void StartProfiler(const DebugOption debugOption) override; + void SetExtensionApiCheckCallback(const std::function &cb) override {} void DebuggerConnectionManager(bool isDebugApp, bool isStartWithDebug, const DebugOption dOption); void ReloadFormComponent(); // Reload ArkTS-Card component diff --git a/interfaces/inner_api/runtime/include/runtime.h b/interfaces/inner_api/runtime/include/runtime.h index 457106ae905..91c6b4d513c 100644 --- a/interfaces/inner_api/runtime/include/runtime.h +++ b/interfaces/inner_api/runtime/include/runtime.h @@ -126,6 +126,7 @@ public: virtual bool UnLoadRepairPatch(const std::string& patchFile) = 0; virtual void RegisterQuickFixQueryFunc(const std::map& moduleAndPath) = 0; virtual void StartProfiler(const DebugOption debugOption) = 0; + virtual void SetExtensionApiCheckCallback(const std::function &cb) {} virtual void DoCleanWorkAfterStageCleaned() {} virtual void SetModuleLoadChecker(const std::shared_ptr moduleCheckerDelegate) const {} virtual void SetDeviceDisconnectCallback(const std::function &cb) = 0; diff --git a/interfaces/kits/native/ability/native/extension_config_mgr.h b/interfaces/kits/native/ability/native/extension_config_mgr.h index 8aa210647d9..16bdef9a556 100644 --- a/interfaces/kits/native/ability/native/extension_config_mgr.h +++ b/interfaces/kits/native/ability/native/extension_config_mgr.h @@ -20,6 +20,7 @@ #include #include +#include "cJSON.h" #include "bundle_info.h" #include "extension_ability_info.h" #include "native_engine/native_engine.h" @@ -28,6 +29,11 @@ namespace OHOS::AbilityRuntime { namespace ExtensionConfigItem { constexpr char ITEM_NAME_BLOCKLIST[] = "blocklist"; + constexpr char ITEM_NAME_REPLACEMODULELIST[] = "replaceModuleList"; + constexpr char ITEM_NAME_OHOSPREFIX[] = "@ohos."; + constexpr char ITEM_NAME_HMSPREFIX[] = "@hms."; + constexpr size_t ITEM_LENGTH_OHOSPREFIX = sizeof(ITEM_NAME_OHOSPREFIX) - 1; + constexpr size_t ITEM_LENGTH_HMSPREFIX = sizeof(ITEM_NAME_HMSPREFIX) - 1; } namespace { constexpr int32_t EXTENSION_TYPE_UNKNOWN = 255; @@ -36,7 +42,7 @@ namespace { /** * @brief Manage extension configuration. */ -class ExtensionConfigMgr { +class ExtensionConfigMgr : public std::enable_shared_from_this { public: ExtensionConfigMgr() = default; @@ -73,9 +79,35 @@ public: */ void UpdateRuntimeModuleChecker(const std::unique_ptr &runtime); + /** + * @brief Check Whether the ets module can be loaded + * + * @param className the className of the ets module + * @return Return true if the module can be loaded, false if the module can not be loaded. + */ + bool CheckEtsModuleLoadable(const std::string &className); + private: + /** + * @brief Parse replace module list from extensionConfig + * + */ + void ParseReplaceModuleLists(const cJSON *extensionConfig); + /** + * @brief Generate ets blocklist be extension_blocklist_config + * + */ + void GenerateExtensionEtsBlocklists(); + /** + * @brief set ets runtime module checker + * + * @param runtime the runtime pointer + */ + void SetExtensionEtsCheckCallback(const std::unique_ptr &runtime); std::unordered_map> blocklistConfig_; std::unordered_map> extensionBlocklist_; + std::unordered_map replaceModuleListConfig_; + std::unordered_set extensionEtsBlocklist_; int32_t extensionType_ = EXTENSION_TYPE_UNKNOWN; }; } // namespace OHOS::AbilityRuntime diff --git a/interfaces/kits/native/appkit/app/main_thread.h b/interfaces/kits/native/appkit/app/main_thread.h index 06141a7fdf4..c5c1800efd6 100644 --- a/interfaces/kits/native/appkit/app/main_thread.h +++ b/interfaces/kits/native/appkit/app/main_thread.h @@ -730,7 +730,7 @@ private: static std::shared_ptr mainHandler_; std::shared_ptr abilityRecordMgr_ = nullptr; std::shared_ptr watchdog_ = nullptr; - std::unique_ptr extensionConfigMgr_ = nullptr; + std::shared_ptr extensionConfigMgr_ = nullptr; MainThreadState mainThreadState_ = MainThreadState::INIT; sptr appMgr_ = nullptr; // appMgrService Handler sptr deathRecipient_ = nullptr; diff --git a/test/mock/frameworks_kits_runtime_test/mock_runtime.h b/test/mock/frameworks_kits_runtime_test/mock_runtime.h index 4540ee79a64..9142fb409f9 100644 --- a/test/mock/frameworks_kits_runtime_test/mock_runtime.h +++ b/test/mock/frameworks_kits_runtime_test/mock_runtime.h @@ -126,7 +126,7 @@ public: } void StartProfiler(const DebugOption debugOption) override {} - + void SetExtensionApiCheckCallback(const std::function &cb) override {} void DumpHeapSnapshot(uint32_t tid, bool isFullGC, bool isBinary = false) override {} void ForceFullGC(uint32_t tid) override {} public: diff --git a/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp b/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp index e751fd2a178..83bc8c12c94 100644 --- a/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp +++ b/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp @@ -15,6 +15,7 @@ #include +#include "cJSON.h" #define private public #define protected public #include "extension_config_mgr.h" @@ -39,6 +40,7 @@ namespace { constexpr int32_t EXTENSION_TYPE_WINDOW = 10; constexpr int32_t EXTENSION_TYPE_ENTERPRISE_ADMIN = 11; constexpr int32_t EXTENSION_TYPE_FILE_ACCESS = 12; + constexpr int32_t EXTENSION_TYPE_DRIVER = 18; constexpr char BLOCK_LIST_ITEM_SERVICE_EXTENSION[] = "ServiceExtension"; constexpr char BLOCK_LIST_ITEM_FORM_EXTENSION[] = "FormExtension"; constexpr char BLOCK_LIST_ITEM_FILE_ACCESS_EXTENSION[] = "FileAccessExtension"; @@ -51,6 +53,9 @@ namespace { constexpr char BLOCK_LIST_ITEM_INPUT_METHOD_EXTENSION_ABILITY[] = "InputMethodExtensionAbility"; constexpr char BLOCK_LIST_ITEM_WORK_SCHEDULER_EXTENSION[] = "WorkSchedulerExtension"; constexpr char BLOCK_LIST_ITEM_DATA_SHARE_EXTENSION[] = "DataShareExtension"; + constexpr char BLOCK_LIST_ITEM_DRIVER_EXTENSION[] = "DriverExtension"; + constexpr char REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY[] = "bundle"; + constexpr char REPLACE_MODULE_LIST_ITEM_BUNDLE_VALUE[] = "bundle.bundle"; constexpr char INVAILD_BLOCK_LIST_ITEM[] = "InvaildExtension"; } @@ -174,5 +179,190 @@ HWTEST_F(ExtensionConfigMgrTest, AddBlockListItem_0200, TestSize.Level1) bool result = (mgr.extensionBlocklist_.find(EXTENSION_TYPE_FORM) != mgr.extensionBlocklist_.end()); EXPECT_FALSE(result); } + +/** + * @tc.name: ParseReplaceModuleLists_0100 + * @tc.desc: ParseReplaceModuleLists fail when blocklist file has no node of replaceModuleList + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0100, TestSize.Level0) +{ + ExtensionConfigMgr mgr; + cJSON *extensionBlockListConfig = cJSON_CreateObject(); + EXPECT_NE(extensionBlockListConfig, nullptr); + + mgr.ParseReplaceModuleLists(extensionBlockListConfig); + bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != + mgr.replaceModuleListConfig_.end()); + EXPECT_FALSE(result); + cJSON_Delete(extensionBlockListConfig); +} + +/** + * @tc.name: ParseReplaceModuleLists_0200 + * @tc.desc: ParseReplaceModuleLists fail when the node of replaceModuleList has no member + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0200, TestSize.Level0) +{ + ExtensionConfigMgr mgr; + cJSON *extensionBlockListConfig = cJSON_CreateObject(); + EXPECT_NE(extensionBlockListConfig, nullptr); + + // Add REPLACEMODULELIST + cJSON *replaceModuleNode = cJSON_CreateObject(); + if (replaceModuleNode == nullptr) { + cJSON_Delete(extensionBlockListConfig); + EXPECT_TRUE(false); + } + cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); + mgr.ParseReplaceModuleLists(extensionBlockListConfig); + bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != + mgr.replaceModuleListConfig_.end()); + EXPECT_FALSE(result); + cJSON_Delete(replaceModuleNode); + cJSON_Delete(extensionBlockListConfig); +} + +/** + * @tc.name: ParseReplaceModuleLists_0300 + * @tc.desc: ParseReplaceModuleLists fail when the value of replaceModuleList node is not string + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0300, TestSize.Level0) +{ + ExtensionConfigMgr mgr; + cJSON *extensionBlockListConfig = cJSON_CreateObject(); + EXPECT_NE(extensionBlockListConfig, nullptr); + + // Add REPLACEMODULELIST + cJSON *replaceModuleNode = cJSON_CreateObject(); + if (replaceModuleNode == nullptr) { + cJSON_Delete(extensionBlockListConfig); + EXPECT_TRUE(false); + } + cJSON_AddItemToObject(replaceModuleNode, REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY, cJSON_CreateNumber(25)); + cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); + mgr.ParseReplaceModuleLists(extensionBlockListConfig); + bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != + mgr.replaceModuleListConfig_.end()); + EXPECT_FALSE(result); + + cJSON_Delete(replaceModuleNode); + cJSON_Delete(extensionBlockListConfig); +} + +/** + * @tc.name: ParseReplaceModuleLists_0400 + * @tc.desc: ParseReplaceModuleLists success + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0400, TestSize.Level0) +{ + ExtensionConfigMgr mgr; + cJSON *extensionBlockListConfig = cJSON_CreateObject(); + EXPECT_NE(extensionBlockListConfig, nullptr); + + // Add REPLACEMODULELIST + cJSON *replaceModuleNode = cJSON_CreateObject(); + if (replaceModuleNode == nullptr) { + cJSON_Delete(extensionBlockListConfig); + EXPECT_TRUE(false); + } + cJSON_AddItemToObject(replaceModuleNode, REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY, cJSON_CreateString("testString")); + cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); + mgr.ParseReplaceModuleLists(extensionBlockListConfig); + auto iter = mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY); + bool result = (iter != mgr.replaceModuleListConfig_.end()); + EXPECT_TRUE(result); + EXPECT_EQ(iter->second, "testString"); + + cJSON_Delete(replaceModuleNode); + cJSON_Delete(extensionBlockListConfig); +} + +/** + * @tc.name: ParseReplaceModuleLists_init_0500 + * @tc.desc: Init And parse success. + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_init_0500, TestSize.Level0) +{ + ExtensionConfigMgr mgr; + mgr.Init(); + auto iter = mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY); + bool result = (iter != mgr.replaceModuleListConfig_.end()); + EXPECT_TRUE(result); + EXPECT_EQ(iter->second, REPLACE_MODULE_LIST_ITEM_BUNDLE_VALUE); +} + +/** + * @tc.name: GenerateExtensionEtsBlocklists_0100 + * @tc.desc: Generate Extension ets block list Test + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, GenerateExtensionEtsBlocklists_0100, TestSize.Level1) +{ + ExtensionConfigMgr mgr; + std::unordered_set set1 = { "111", "222", "333" }; + mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set1); + mgr.extensionType_ = EXTENSION_TYPE_WORK_SCHEDULER; + mgr.GenerateExtensionEtsBlocklists(); + EXPECT_TRUE(mgr.extensionEtsBlocklist_.empty()); + + mgr.extensionBlocklist_.clear(); + mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set1); + mgr.extensionType_ = EXTENSION_TYPE_FORM; + mgr.GenerateExtensionEtsBlocklists(); + EXPECT_FALSE(mgr.extensionEtsBlocklist_.empty()); + for (const auto& ele: set1) { + EXPECT_TRUE(mgr.extensionEtsBlocklist_.find(ele) != mgr.extensionEtsBlocklist_.end()); + } + + mgr.replaceModuleListConfig_.emplace("222", "222_1"); + mgr.extensionBlocklist_.clear(); + mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set1); + mgr.extensionType_ = EXTENSION_TYPE_FORM; + mgr.GenerateExtensionEtsBlocklists(); + EXPECT_FALSE(mgr.extensionEtsBlocklist_.empty()); + EXPECT_FLASE(mgr.extensionEtsBlocklist_.find("222") != mgr.extensionEtsBlocklist_.end()); + EXPECT_TRUE(mgr.extensionEtsBlocklist_.find("222_1") != mgr.extensionEtsBlocklist_.end()); + + std::unordered_set set2 = { "BbB" }; + mgr.replaceModuleListConfig_.clear(); + mgr.extensionBlocklist_.clear(); + mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set2); + mgr.extensionType_ = EXTENSION_TYPE_FORM; + mgr.GenerateExtensionEtsBlocklists(); + EXPECT_FALSE(mgr.extensionEtsBlocklist_.empty()); + EXPECT_FALSE(mgr.extensionEtsBlocklist_.find("BbB") != mgr.extensionEtsBlocklist_.end()); + EXPECT_TRUE(mgr.extensionEtsBlocklist_.find("bbb") != mgr.extensionEtsBlocklist_.end()); +} + +/** + * @tc.name: CheckEtsModuleLoadable_0100 + * @tc.desc: CheckEtsModuleLoadable Test + * @tc.type: FUNC + */ +HWTEST_F(ExtensionConfigMgrTest, CheckEtsModuleLoadable_0100, TestSize.Level1) +{ + ExtensionConfigMgr mgr; + mgr.Init(); + mgr.AddBlockListItem(BLOCK_LIST_ITEM_DRIVER_EXTENSION, EXTENSION_TYPE_DRIVER); + mgr.extensionType_ = EXTENSION_TYPE_DRIVER; + mgr.GenerateExtensionEtsBlocklists(); + + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("abilityAccessCtrl")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("ABILITYACCESSCTRL")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("abilityAccessCtrl.XXX")); + EXPECT_TRUE(mgr.CheckEtsModuleLoadable("bundle")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("bundle.bundle")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("app.ability.appManager")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("@ohos.app.ability.appManager")); + EXPECT_FALSE(mgr.CheckEtsModuleLoadable("@hms.app.ability.appManager")); + EXPECT_TRUE(mgr.CheckEtsModuleLoadable("@hms.app.app.appManager")); + EXPECT_TRUE(mgr.CheckEtsModuleLoadable("@ohos.app.app.appManager")); + EXPECT_TRUE(mgr.CheckEtsModuleLoadable("1111")); +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/test/unittest/insight_intent/mock/mock_runtime.h b/test/unittest/insight_intent/mock/mock_runtime.h index 2348284d14d..b3b6ca82caf 100644 --- a/test/unittest/insight_intent/mock/mock_runtime.h +++ b/test/unittest/insight_intent/mock/mock_runtime.h @@ -56,6 +56,7 @@ public: bool UnLoadRepairPatch(const std::string& patchFile) override { return false; } void RegisterQuickFixQueryFunc(const std::map& moduleAndPath) override {} void StartProfiler(const DebugOption debugOption) override {} + void SetExtensionApiCheckCallback(const std::function &cb) override {} void SetDeviceDisconnectCallback(const std::function &cb) override {} void SetLanguage(const Runtime::Language& language) { language_ = language; } private: -- Gitee From 14a234aa8cc71c82be711b3a5208861ab4934f4a Mon Sep 17 00:00:00 2001 From: y00620503 Date: Mon, 7 Jul 2025 11:10:27 +0800 Subject: [PATCH 2/2] back cjson head file use Signed-off-by: y00620503 --- .../ability/native/extension_config_mgr.cpp | 42 +++---- .../ability/native/extension_config_mgr.h | 6 - .../extension_config_mgr_test.cpp | 110 +----------------- 3 files changed, 24 insertions(+), 134 deletions(-) diff --git a/frameworks/native/ability/native/extension_config_mgr.cpp b/frameworks/native/ability/native/extension_config_mgr.cpp index df4c956db9f..2a0c04e23be 100644 --- a/frameworks/native/ability/native/extension_config_mgr.cpp +++ b/frameworks/native/ability/native/extension_config_mgr.cpp @@ -28,26 +28,6 @@ namespace { constexpr char EXTENSION_BLOCKLIST_FILE_PATH[] = "/system/etc/extension_blocklist_config.json"; } -void ExtensionConfigMgr::ParseReplaceModuleLists(const cJSON *extensionConfig) -{ - cJSON *replaceModuleItem = cJSON_GetObjectItem(extensionConfig, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST); - if (replaceModuleItem == nullptr) { - TAG_LOGE(AAFwkTag::EXT, "extension config file have no replace module list node"); - return; - } - cJSON *childItem = replaceModuleItem->child; - while (childItem != nullptr) { - if (!cJSON_IsString(childItem)) { - continue; - } - std::string key = childItem->string == nullptr ? "" : childItem->string; - std::string value = childItem->valuestring; - replaceModuleListConfig_.emplace(key, value); - - childItem = childItem->next; - } -} - void ExtensionConfigMgr::Init() { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -96,7 +76,21 @@ void ExtensionConfigMgr::Init() childItem = childItem->next; } - ParseReplaceModuleLists(extensionConfig); + cJSON *replaceModuleItem = cJSON_GetObjectItem(extensionConfig, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST); + if (replaceModuleItem == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "extension config file have no replace module list node"); + return; + } + childItem = replaceModuleItem->child; + while (childItem != nullptr) { + if (!cJSON_IsString(childItem)) { + continue; + } + std::string key = childItem->string == nullptr ? "" : childItem->string; + std::string value = childItem->valuestring; + replaceModuleListConfig_.emplace(key, value); + childItem = childItem->next; + } cJSON_Delete(extensionConfig); TAG_LOGD(AAFwkTag::EXT, "Init end"); } @@ -175,9 +169,9 @@ bool ExtensionConfigMgr::CheckEtsModuleLoadable(const std::string &className) classNameAfterRemovePreFix = className; } std::string lowerClassName; - lowerClassName.reserve(className.size()); - std::transform(className.cbegin(), className.cend(), std::back_inserter(lowerClassName), - [](unsigned char c) { return std::tolower(c); }); + lowerClassName.reserve(classNameAfterRemovePreFix.size()); + std::transform(classNameAfterRemovePreFix.cbegin(), classNameAfterRemovePreFix.cend(), + std::back_inserter(lowerClassName), [](unsigned char c) { return std::tolower(c); }); TAG_LOGD(AAFwkTag::EXT, "extensionType: %{public}d, className is %{public}s.", extensionType_, className.c_str()); for (const auto& blockClassName: extensionEtsBlocklist_) { if (lowerClassName.compare(0, blockClassName.length(), blockClassName) == 0) { diff --git a/interfaces/kits/native/ability/native/extension_config_mgr.h b/interfaces/kits/native/ability/native/extension_config_mgr.h index 16bdef9a556..281a6785f1a 100644 --- a/interfaces/kits/native/ability/native/extension_config_mgr.h +++ b/interfaces/kits/native/ability/native/extension_config_mgr.h @@ -20,7 +20,6 @@ #include #include -#include "cJSON.h" #include "bundle_info.h" #include "extension_ability_info.h" #include "native_engine/native_engine.h" @@ -88,11 +87,6 @@ public: bool CheckEtsModuleLoadable(const std::string &className); private: - /** - * @brief Parse replace module list from extensionConfig - * - */ - void ParseReplaceModuleLists(const cJSON *extensionConfig); /** * @brief Generate ets blocklist be extension_blocklist_config * diff --git a/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp b/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp index 83bc8c12c94..805167c5995 100644 --- a/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp +++ b/test/unittest/extension_config_mgr_test/extension_config_mgr_test.cpp @@ -181,118 +181,18 @@ HWTEST_F(ExtensionConfigMgrTest, AddBlockListItem_0200, TestSize.Level1) } /** - * @tc.name: ParseReplaceModuleLists_0100 - * @tc.desc: ParseReplaceModuleLists fail when blocklist file has no node of replaceModuleList - * @tc.type: FUNC - */ -HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0100, TestSize.Level0) -{ - ExtensionConfigMgr mgr; - cJSON *extensionBlockListConfig = cJSON_CreateObject(); - EXPECT_NE(extensionBlockListConfig, nullptr); - - mgr.ParseReplaceModuleLists(extensionBlockListConfig); - bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != - mgr.replaceModuleListConfig_.end()); - EXPECT_FALSE(result); - cJSON_Delete(extensionBlockListConfig); -} - -/** - * @tc.name: ParseReplaceModuleLists_0200 - * @tc.desc: ParseReplaceModuleLists fail when the node of replaceModuleList has no member - * @tc.type: FUNC - */ -HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0200, TestSize.Level0) -{ - ExtensionConfigMgr mgr; - cJSON *extensionBlockListConfig = cJSON_CreateObject(); - EXPECT_NE(extensionBlockListConfig, nullptr); - - // Add REPLACEMODULELIST - cJSON *replaceModuleNode = cJSON_CreateObject(); - if (replaceModuleNode == nullptr) { - cJSON_Delete(extensionBlockListConfig); - EXPECT_TRUE(false); - } - cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); - mgr.ParseReplaceModuleLists(extensionBlockListConfig); - bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != - mgr.replaceModuleListConfig_.end()); - EXPECT_FALSE(result); - cJSON_Delete(replaceModuleNode); - cJSON_Delete(extensionBlockListConfig); -} - -/** - * @tc.name: ParseReplaceModuleLists_0300 - * @tc.desc: ParseReplaceModuleLists fail when the value of replaceModuleList node is not string - * @tc.type: FUNC - */ -HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0300, TestSize.Level0) -{ - ExtensionConfigMgr mgr; - cJSON *extensionBlockListConfig = cJSON_CreateObject(); - EXPECT_NE(extensionBlockListConfig, nullptr); - - // Add REPLACEMODULELIST - cJSON *replaceModuleNode = cJSON_CreateObject(); - if (replaceModuleNode == nullptr) { - cJSON_Delete(extensionBlockListConfig); - EXPECT_TRUE(false); - } - cJSON_AddItemToObject(replaceModuleNode, REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY, cJSON_CreateNumber(25)); - cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); - mgr.ParseReplaceModuleLists(extensionBlockListConfig); - bool result = (mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY) != - mgr.replaceModuleListConfig_.end()); - EXPECT_FALSE(result); - - cJSON_Delete(replaceModuleNode); - cJSON_Delete(extensionBlockListConfig); -} - -/** - * @tc.name: ParseReplaceModuleLists_0400 - * @tc.desc: ParseReplaceModuleLists success - * @tc.type: FUNC - */ -HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_0400, TestSize.Level0) -{ - ExtensionConfigMgr mgr; - cJSON *extensionBlockListConfig = cJSON_CreateObject(); - EXPECT_NE(extensionBlockListConfig, nullptr); - - // Add REPLACEMODULELIST - cJSON *replaceModuleNode = cJSON_CreateObject(); - if (replaceModuleNode == nullptr) { - cJSON_Delete(extensionBlockListConfig); - EXPECT_TRUE(false); - } - cJSON_AddItemToObject(replaceModuleNode, REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY, cJSON_CreateString("testString")); - cJSON_AddItemToObject(person, ExtensionConfigItem::ITEM_NAME_REPLACEMODULELIST, replaceModuleNode); - mgr.ParseReplaceModuleLists(extensionBlockListConfig); - auto iter = mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY); - bool result = (iter != mgr.replaceModuleListConfig_.end()); - EXPECT_TRUE(result); - EXPECT_EQ(iter->second, "testString"); - - cJSON_Delete(replaceModuleNode); - cJSON_Delete(extensionBlockListConfig); -} - -/** - * @tc.name: ParseReplaceModuleLists_init_0500 + * @tc.name: ParseReplaceModuleLists_init_0100 * @tc.desc: Init And parse success. * @tc.type: FUNC */ -HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_init_0500, TestSize.Level0) +HWTEST_F(ExtensionConfigMgrTest, ParseReplaceModuleLists_init_0100, TestSize.Level0) { ExtensionConfigMgr mgr; mgr.Init(); auto iter = mgr.replaceModuleListConfig_.find(REPLACE_MODULE_LIST_ITEM_BUNDLE_KEY); bool result = (iter != mgr.replaceModuleListConfig_.end()); EXPECT_TRUE(result); + EXPECT_EQ(iter->second, REPLACE_MODULE_LIST_ITEM_BUNDLE_VALUE); } @@ -321,16 +221,18 @@ HWTEST_F(ExtensionConfigMgrTest, GenerateExtensionEtsBlocklists_0100, TestSize.L mgr.replaceModuleListConfig_.emplace("222", "222_1"); mgr.extensionBlocklist_.clear(); + mgr.extensionEtsBlocklist_.clear(); mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set1); mgr.extensionType_ = EXTENSION_TYPE_FORM; mgr.GenerateExtensionEtsBlocklists(); EXPECT_FALSE(mgr.extensionEtsBlocklist_.empty()); - EXPECT_FLASE(mgr.extensionEtsBlocklist_.find("222") != mgr.extensionEtsBlocklist_.end()); + EXPECT_FALSE(mgr.extensionEtsBlocklist_.find("222") != mgr.extensionEtsBlocklist_.end()); EXPECT_TRUE(mgr.extensionEtsBlocklist_.find("222_1") != mgr.extensionEtsBlocklist_.end()); std::unordered_set set2 = { "BbB" }; mgr.replaceModuleListConfig_.clear(); mgr.extensionBlocklist_.clear(); + mgr.extensionEtsBlocklist_.clear(); mgr.extensionBlocklist_.emplace(EXTENSION_TYPE_FORM, set2); mgr.extensionType_ = EXTENSION_TYPE_FORM; mgr.GenerateExtensionEtsBlocklists(); -- Gitee