diff --git a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp index 06569c4930..c9fb996e54 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp @@ -2515,32 +2515,71 @@ void JsUIAbility::NotifyWindowDestroy() } } +namespace { +std::string ExtractBaseName(const std::string &path) +{ + auto slashPos = path.rfind('/'); + auto dotPos = path.rfind('.'); + if (slashPos == std::string::npos) { + slashPos = 0; + } else { + slashPos++; + } + if (dotPos == std::string::npos || dotPos <= slashPos) { + return path.substr(slashPos); + } + return path.substr(slashPos, dotPos - slashPos); +} +} // namespace + napi_value JsUIAbility::LoadSkillFunction( const std::shared_ptr ¶m, napi_value &outJsObj) { napi_env env = jsRuntime_.GetNapiEnv(); std::unique_ptr moduleRef = nullptr; napi_value method = nullptr; - for (const auto &srcEntry : param->srcEntries_) { + + auto TryLoadEntry = [&](const std::string &srcEntry) -> bool { std::string srcPath(param->moduleName_ + "/" + srcEntry); auto pos = srcPath.rfind('.'); if (pos == std::string::npos) { TAG_LOGW(AAFwkTag::UIABILITY, "skip srcEntry, no extension:%{public}s", srcEntry.c_str()); - continue; + return false; } srcPath.erase(pos); srcPath.append(".abc"); moduleRef = jsRuntime_.LoadModule(param->moduleName_, srcPath, param->hapPath_, true); if (moduleRef == nullptr) { TAG_LOGW(AAFwkTag::UIABILITY, "LoadModule failed, path:%{public}s", srcPath.c_str()); - continue; + return false; } outJsObj = moduleRef->GetNapiValue(); method = AppExecFwk::GetPropertyValueByPropertyName( env, outJsObj, param->functionName_.c_str(), napi_valuetype::napi_function); - if (method != nullptr) { + return method != nullptr; + }; + + if (!param->scriptPath_.empty()) { + auto scriptBase = ExtractBaseName(param->scriptPath_); + for (const auto &srcEntry : param->srcEntries_) { + if (ExtractBaseName(srcEntry) != scriptBase) { + continue; + } + if (TryLoadEntry(srcEntry)) { + TAG_LOGI(AAFwkTag::UIABILITY, + "func found via scriptPath match, srcEntry:%{public}s", srcEntry.c_str()); + return method; + } + } + TAG_LOGW(AAFwkTag::UIABILITY, + "scriptPath match failed, fallback to full scan, scriptPath:%{public}s", + param->scriptPath_.c_str()); + } + + for (const auto &srcEntry : param->srcEntries_) { + if (TryLoadEntry(srcEntry)) { TAG_LOGI(AAFwkTag::UIABILITY, "func found in srcEntry:%{public}s", srcEntry.c_str()); - break; + return method; } TAG_LOGW(AAFwkTag::UIABILITY, "func not found:%{public}s in srcEntry:%{public}s", param->functionName_.c_str(), srcEntry.c_str()); diff --git a/frameworks/native/ability/native/js_service_extension.cpp b/frameworks/native/ability/native/js_service_extension.cpp index fae8fdc54b..1ba3907461 100644 --- a/frameworks/native/ability/native/js_service_extension.cpp +++ b/frameworks/native/ability/native/js_service_extension.cpp @@ -579,32 +579,71 @@ bool JsServiceExtension::HandleExecuteSkill(const AAFwk::Want &want) return true; } +namespace { +std::string ExtractBaseName(const std::string &path) +{ + auto slashPos = path.rfind('/'); + auto dotPos = path.rfind('.'); + if (slashPos == std::string::npos) { + slashPos = 0; + } else { + slashPos++; + } + if (dotPos == std::string::npos || dotPos <= slashPos) { + return path.substr(slashPos); + } + return path.substr(slashPos, dotPos - slashPos); +} +} // namespace + napi_value JsServiceExtension::LoadSkillFunction( const std::shared_ptr ¶m, napi_value &outJsObj) { napi_env env = jsRuntime_.GetNapiEnv(); std::unique_ptr moduleRef = nullptr; napi_value method = nullptr; - for (const auto &srcEntry : param->srcEntries_) { + + auto TryLoadEntry = [&](const std::string &srcEntry) -> bool { std::string srcPath(param->moduleName_ + "/" + srcEntry); auto pos = srcPath.rfind('.'); if (pos == std::string::npos) { TAG_LOGW(AAFwkTag::SERVICE_EXT, "skip srcEntry, no extension:%{public}s", srcEntry.c_str()); - continue; + return false; } srcPath.erase(pos); srcPath.append(".abc"); moduleRef = jsRuntime_.LoadModule(param->moduleName_, srcPath, param->hapPath_, true); if (moduleRef == nullptr) { TAG_LOGW(AAFwkTag::SERVICE_EXT, "LoadModule failed, path:%{public}s", srcPath.c_str()); - continue; + return false; } outJsObj = moduleRef->GetNapiValue(); method = AppExecFwk::GetPropertyValueByPropertyName( env, outJsObj, param->functionName_.c_str(), napi_valuetype::napi_function); - if (method != nullptr) { + return method != nullptr; + }; + + if (!param->scriptPath_.empty()) { + auto scriptBase = ExtractBaseName(param->scriptPath_); + for (const auto &srcEntry : param->srcEntries_) { + if (ExtractBaseName(srcEntry) != scriptBase) { + continue; + } + if (TryLoadEntry(srcEntry)) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, + "func found via scriptPath match, srcEntry:%{public}s", srcEntry.c_str()); + return method; + } + } + TAG_LOGW(AAFwkTag::SERVICE_EXT, + "scriptPath match failed, fallback to full scan, scriptPath:%{public}s", + param->scriptPath_.c_str()); + } + + for (const auto &srcEntry : param->srcEntries_) { + if (TryLoadEntry(srcEntry)) { TAG_LOGI(AAFwkTag::SERVICE_EXT, "func found in srcEntry:%{public}s", srcEntry.c_str()); - break; + return method; } TAG_LOGW(AAFwkTag::SERVICE_EXT, "func not found:%{public}s in srcEntry:%{public}s", param->functionName_.c_str(), srcEntry.c_str());