feat: use scriptPath to filter srcEntries in LoadSkillFunction

Extract basename from scriptPath (e.g. "scripts/TotalTimeSkill.ets"
→ "TotalTimeSkill") and match against srcEntries basename. If matched,
load only that entry first. Fall back to full scan if no match found.

Co-Authored-By: Agent
Change-Id: I6f6f8f44bbd59b7847b2a4b649a452d2c03526b1
Signed-off-by: RuiChen_01 <chenrui193@huawei.com>
This commit is contained in:
RuiChen_01
2026-05-16 19:48:02 +08:00
parent b31fa93cfa
commit cca5dbac20
2 changed files with 88 additions and 10 deletions
@@ -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<AppExecFwk::SkillExecuteParam> &param, napi_value &outJsObj)
{
napi_env env = jsRuntime_.GetNapiEnv();
std::unique_ptr<NativeReference> 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());
@@ -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<AppExecFwk::SkillExecuteParam> &param, napi_value &outJsObj)
{
napi_env env = jsRuntime_.GetNapiEnv();
std::unique_ptr<NativeReference> 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());