mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
Update unzip load code.
Signed-off-by: dy_study <dingyao5@huawei.com> Change-Id: I386bdc51a10afaaf0e5f30e84b1079b138b4b2c7
This commit is contained in:
@@ -113,7 +113,8 @@ void JsAbility::Init(const std::shared_ptr<AbilityInfo> &abilityInfo,
|
||||
auto &engine = jsRuntime_.GetNativeEngine();
|
||||
|
||||
jsAbilityObj_ =
|
||||
jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, abilityInfo->hapPath);
|
||||
jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->hapPath,
|
||||
abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE);
|
||||
if (jsAbilityObj_ == nullptr) {
|
||||
HILOG_ERROR("Failed to get AbilityStage object");
|
||||
return;
|
||||
|
||||
@@ -92,7 +92,8 @@ void JsFormExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
|
||||
HandleScope handleScope(jsRuntime_);
|
||||
auto& engine = jsRuntime_.GetNativeEngine();
|
||||
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath);
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
|
||||
abilityInfo_->compileMode == CompileMode::ES_MODULE);
|
||||
if (jsObj_ == nullptr) {
|
||||
HILOG_ERROR("Failed to get jsObj_");
|
||||
return;
|
||||
|
||||
@@ -90,7 +90,8 @@ void JsServiceExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
|
||||
HandleScope handleScope(jsRuntime_);
|
||||
auto& engine = jsRuntime_.GetNativeEngine();
|
||||
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath);
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
|
||||
abilityInfo_->compileMode == CompileMode::ES_MODULE);
|
||||
if (jsObj_ == nullptr) {
|
||||
HILOG_ERROR("Failed to get jsObj_");
|
||||
return;
|
||||
|
||||
@@ -92,7 +92,8 @@ void JsStaticSubscriberExtension::Init(const std::shared_ptr<AbilityLocalRecord>
|
||||
HandleScope handleScope(jsRuntime_);
|
||||
auto& engine = jsRuntime_.GetNativeEngine();
|
||||
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath);
|
||||
jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
|
||||
abilityInfo_->compileMode == CompileMode::ES_MODULE);
|
||||
if (jsObj_ == nullptr) {
|
||||
HILOG_ERROR("Failed to get jsObj_");
|
||||
return;
|
||||
|
||||
@@ -68,8 +68,8 @@ JsTestRunner::JsTestRunner(
|
||||
std::string moduleName;
|
||||
hapPath_ = bundleInfo.hapModuleInfos.back().hapPath;
|
||||
HILOG_DEBUG("JsTestRunner hapPath is %{public}s", hapPath_.c_str());
|
||||
jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_,
|
||||
bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE, hapPath_);
|
||||
jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, hapPath_,
|
||||
bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ JsTestRunner::~JsTestRunner() = default;
|
||||
bool JsTestRunner::Initialize()
|
||||
{
|
||||
if (isFaJsModel_) {
|
||||
if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc")) {
|
||||
if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", hapPath_)) {
|
||||
HILOG_ERROR("RunScript err");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ std::shared_ptr<AbilityStage> JsAbilityStage::Create(
|
||||
std::string moduleName(hapModuleInfo.moduleName);
|
||||
moduleName.append("::").append("AbilityStage");
|
||||
auto moduleObj =
|
||||
jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath);
|
||||
jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath,
|
||||
hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE);
|
||||
return std::make_shared<JsAbilityStage>(jsRuntime, std::move(moduleObj));
|
||||
}
|
||||
|
||||
@@ -83,7 +84,8 @@ std::shared_ptr<AbilityStage> JsAbilityStage::Create(
|
||||
std::string moduleName(hapModuleInfo.moduleName);
|
||||
moduleName.append("::").append("AbilityStage");
|
||||
moduleObj =
|
||||
jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath);
|
||||
jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath,
|
||||
hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE);
|
||||
HILOG_INFO("JsAbilityStage srcPath is %{public}s", srcPath.c_str());
|
||||
}
|
||||
return std::make_shared<JsAbilityStage>(jsRuntime, std::move(moduleObj));
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 "js_module_reader.h"
|
||||
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_runtime_utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
std::vector<uint8_t> JsModuleReader::operator()(
|
||||
const std::string& curJsModulePath, const std::string& newJsModuleUri) const
|
||||
{
|
||||
HILOG_INFO("Read JS module (%{public}s, %{public}s) begin", curJsModulePath.c_str(), newJsModuleUri.c_str());
|
||||
|
||||
std::vector<uint8_t> buffer;
|
||||
if (curJsModulePath.empty() || newJsModuleUri.empty()) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string normalizeUri = newJsModuleUri;
|
||||
std::replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/');
|
||||
|
||||
std::string newJsModulePath;
|
||||
switch (normalizeUri[0]) {
|
||||
case '.': {
|
||||
newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri);
|
||||
break;
|
||||
}
|
||||
case '@': {
|
||||
newJsModulePath = ParseOhmUri(bundleName_, curJsModulePath, normalizeUri);
|
||||
if (newJsModulePath.empty()) {
|
||||
newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
FixExtName(newJsModulePath);
|
||||
|
||||
std::ostringstream dest;
|
||||
if (!GetFileBufferFromHap(hapPath_, newJsModulePath, dest)) {
|
||||
HILOG_ERROR("Get abc file failed");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const auto& outStr = dest.str();
|
||||
buffer.assign(outStr.begin(), outStr.end());
|
||||
|
||||
HILOG_INFO("Read JS module (%{public}s, %{public}s) => %{public}s end",
|
||||
curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str());
|
||||
|
||||
return buffer;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_JS_MODULE_READER_H
|
||||
#define OHOS_ABILITY_RUNTIME_JS_MODULE_READER_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class JsModuleReader final {
|
||||
public:
|
||||
explicit JsModuleReader(const std::string& bundleName, const std::string& hapPath)
|
||||
: bundleName_(bundleName), hapPath_(hapPath)
|
||||
{}
|
||||
~JsModuleReader() = default;
|
||||
|
||||
JsModuleReader(const JsModuleReader&) = default;
|
||||
JsModuleReader(JsModuleReader&&) = default;
|
||||
JsModuleReader& operator=(const JsModuleReader&) = default;
|
||||
JsModuleReader& operator=(JsModuleReader&&) = default;
|
||||
|
||||
std::vector<uint8_t> operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const;
|
||||
|
||||
private:
|
||||
std::string bundleName_;
|
||||
std::string hapPath_;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_ABILITY_RUNTIME_JS_MODULE_READER_H
|
||||
@@ -15,370 +15,32 @@
|
||||
|
||||
#include "js_module_searcher.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_runtime_utils.h"
|
||||
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
#include <io.h>
|
||||
|
||||
namespace {
|
||||
char* realpath(const char* path, char* resolvedPath)
|
||||
{
|
||||
if (_access(path, 0) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (strcpy_s(resolvedPath, PATH_MAX, path) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return resolvedPath;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
constexpr char PREFIX_BUNDLE[] = "@bundle:";
|
||||
constexpr char PREFIX_MODULE[] = "@module:";
|
||||
constexpr char PREFIX_LOCAL[] = "@local:";
|
||||
|
||||
constexpr char NPM_PATH_SEGMENT[] = "node_modules";
|
||||
|
||||
constexpr char NPM_ENTRY_FILE[] = "index.abc";
|
||||
constexpr char NPM_ENTRY_LINK[] = "entry.txt";
|
||||
|
||||
constexpr char EXT_NAME_ABC[] = ".abc";
|
||||
constexpr char EXT_NAME_ETS[] = ".ets";
|
||||
constexpr char EXT_NAME_TS[] = ".ts";
|
||||
constexpr char EXT_NAME_JS[] = ".js";
|
||||
|
||||
constexpr size_t MAX_NPM_LEVEL = 1;
|
||||
|
||||
inline bool StringEndWith(const std::string& str, const char* endStr, size_t endStrLen)
|
||||
{
|
||||
size_t len = str.length();
|
||||
return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0));
|
||||
}
|
||||
|
||||
void SplitString(const std::string& str, std::vector<std::string>& out, size_t pos = 0, const char* seps = "\\/")
|
||||
{
|
||||
if (str.empty() || pos >= str.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t startPos = pos;
|
||||
size_t endPos = 0;
|
||||
while ((endPos = str.find_first_of(seps, startPos)) != std::string::npos) {
|
||||
if (endPos > startPos) {
|
||||
out.emplace_back(str.substr(startPos, endPos - startPos));
|
||||
}
|
||||
startPos = endPos + 1;
|
||||
}
|
||||
|
||||
if (startPos < str.length()) {
|
||||
out.emplace_back(str.substr(startPos));
|
||||
}
|
||||
}
|
||||
|
||||
std::string JoinString(const std::vector<std::string>& strs, char sep, size_t startIndex = 0)
|
||||
{
|
||||
std::string out;
|
||||
for (size_t index = startIndex; index < strs.size(); ++index) {
|
||||
if (!strs[index].empty()) {
|
||||
out.append(strs[index]) += sep;
|
||||
}
|
||||
}
|
||||
if (!out.empty()) {
|
||||
out.pop_back();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::string StripString(const std::string& str, const char* charSet = " \t\n\r")
|
||||
{
|
||||
size_t startPos = str.find_first_not_of(charSet);
|
||||
if (startPos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return str.substr(startPos, str.find_last_not_of(charSet) - startPos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const
|
||||
{
|
||||
return ParseJsModuleUri(curJsModulePath, newJsModuleUri);
|
||||
}
|
||||
|
||||
void JsModuleSearcher::FixExtName(std::string& path)
|
||||
{
|
||||
if (path.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringEndWith(path, EXT_NAME_ABC, sizeof(EXT_NAME_ABC) - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringEndWith(path, EXT_NAME_ETS, sizeof(EXT_NAME_ETS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_ETS) - 1), sizeof(EXT_NAME_ETS) - 1);
|
||||
} else if (StringEndWith(path, EXT_NAME_TS, sizeof(EXT_NAME_TS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_TS) - 1), sizeof(EXT_NAME_TS) - 1);
|
||||
} else if (StringEndWith(path, EXT_NAME_JS, sizeof(EXT_NAME_JS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_JS) - 1), sizeof(EXT_NAME_JS) - 1);
|
||||
}
|
||||
|
||||
path.append(EXT_NAME_ABC);
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::GetInstallPath(const std::string& curJsModulePath, bool module) const
|
||||
{
|
||||
size_t pos = std::string::npos;
|
||||
if (StringStartWith(curJsModulePath, bundleInstallPath_.c_str(), bundleInstallPath_.length())) {
|
||||
pos = bundleInstallPath_.length() - 1;
|
||||
} else {
|
||||
if (!StringStartWith(curJsModulePath, otherBundleInstallPath_.c_str(), otherBundleInstallPath_.length())) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
pos = curJsModulePath.find('/', otherBundleInstallPath_.length());
|
||||
if (pos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
if (module) {
|
||||
pos = curJsModulePath.find('/', pos + 1);
|
||||
if (pos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
return curJsModulePath.substr(0, pos + 1);
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::MakeNewJsModulePath(
|
||||
const std::string& curJsModulePath, const std::string& newJsModuleUri) const
|
||||
{
|
||||
std::string moduleInstallPath = GetInstallPath(curJsModulePath, true);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::vector<std::string> pathVector;
|
||||
SplitString(curJsModulePath, pathVector, moduleInstallPath.length());
|
||||
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Remove file name, reserve only dir name
|
||||
pathVector.pop_back();
|
||||
|
||||
std::vector<std::string> relativePathVector;
|
||||
SplitString(newJsModuleUri, relativePathVector);
|
||||
|
||||
for (auto& value : relativePathVector) {
|
||||
if (value == ".") {
|
||||
continue;
|
||||
} else if (value == "..") {
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
pathVector.pop_back();
|
||||
} else {
|
||||
pathVector.emplace_back(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
std::string jsModulePath = moduleInstallPath + JoinString(pathVector, '/');
|
||||
FixExtName(jsModulePath);
|
||||
if (jsModulePath.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (realpath(jsModulePath.c_str(), path) != nullptr) {
|
||||
return std::string(path);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::FindNpmPackageInPath(const std::string& npmPath) const
|
||||
{
|
||||
std::string fileName = npmPath + "/" + NPM_ENTRY_FILE;
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (fileName.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
if (realpath(fileName.c_str(), path) != nullptr) {
|
||||
return path;
|
||||
}
|
||||
|
||||
fileName = npmPath + "/" + NPM_ENTRY_LINK;
|
||||
if (fileName.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
if (realpath(fileName.c_str(), path) == nullptr) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::ifstream stream(path, std::ios::ate);
|
||||
if (!stream.is_open()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto fileLen = stream.tellg();
|
||||
if (fileLen >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
stream.seekg(0);
|
||||
stream.read(path, fileLen);
|
||||
path[fileLen] = '\0';
|
||||
return npmPath + '/' + StripString(path);
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::FindNpmPackageInTopLevel(
|
||||
const std::string& moduleInstallPath, const std::string& npmPackage, size_t start) const
|
||||
{
|
||||
for (size_t level = start; level <= MAX_NPM_LEVEL; ++level) {
|
||||
std::string path = moduleInstallPath + NPM_PATH_SEGMENT + '/' + std::to_string(level) + '/' + npmPackage;
|
||||
path = FindNpmPackageInPath(path);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage) const
|
||||
{
|
||||
std::string newJsModulePath = MakeNewJsModulePath(curJsModulePath, npmPackage);
|
||||
if (!newJsModulePath.empty()) {
|
||||
return newJsModulePath;
|
||||
}
|
||||
std::string moduleInstallPath = GetInstallPath(curJsModulePath);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
std::vector<std::string> pathVector;
|
||||
SplitString(curJsModulePath, pathVector, moduleInstallPath.length());
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (pathVector[0] != NPM_PATH_SEGMENT) {
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage);
|
||||
}
|
||||
|
||||
// Remove file name, reserve only dir name
|
||||
pathVector.pop_back();
|
||||
|
||||
// Find npm package until reach top level npm path such as 'node_modules/0',
|
||||
// so there must be 2 element in vector
|
||||
while (pathVector.size() > 2) {
|
||||
std::string path =
|
||||
moduleInstallPath + JoinString(pathVector, '/') + '/' + NPM_PATH_SEGMENT + '/' + npmPackage;
|
||||
path = FindNpmPackageInPath(path);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
pathVector.pop_back();
|
||||
}
|
||||
|
||||
char* p = nullptr;
|
||||
size_t index = std::strtoul(pathVector.back().c_str(), &p, 10);
|
||||
if (p == nullptr || *p != '\0') {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage, index);
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::ParseOhmUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const
|
||||
{
|
||||
std::string moduleInstallPath;
|
||||
std::vector<std::string> pathVector;
|
||||
size_t index = 0;
|
||||
|
||||
if (StringStartWith(newJsModuleUri, PREFIX_BUNDLE, sizeof(PREFIX_BUNDLE) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_BUNDLE) - 1);
|
||||
|
||||
// Uri should have atleast 3 segments
|
||||
if (pathVector.size() < 3) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const auto& bundleName = pathVector[index++];
|
||||
if (bundleName == bundleName_) {
|
||||
moduleInstallPath = bundleInstallPath_;
|
||||
} else {
|
||||
moduleInstallPath = otherBundleInstallPath_;
|
||||
moduleInstallPath.append(bundleName).append("/");
|
||||
}
|
||||
moduleInstallPath.append(pathVector[index++]).append("/");
|
||||
} else if (StringStartWith(newJsModuleUri, PREFIX_MODULE, sizeof(PREFIX_MODULE) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_MODULE) - 1);
|
||||
|
||||
// Uri should have atleast 2 segments
|
||||
if (pathVector.size() < 2) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
moduleInstallPath = GetInstallPath(curJsModulePath, false);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
moduleInstallPath.append(pathVector[index++]).append("/");
|
||||
} else if (StringStartWith(newJsModuleUri, PREFIX_LOCAL, sizeof(PREFIX_LOCAL) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_LOCAL) - 1);
|
||||
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
moduleInstallPath = GetInstallPath(curJsModulePath);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (pathVector[index] != NPM_PATH_SEGMENT) {
|
||||
return moduleInstallPath + JoinString(pathVector, '/', index);
|
||||
}
|
||||
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, JoinString(pathVector, '/', index + 1));
|
||||
}
|
||||
|
||||
std::string JsModuleSearcher::ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const
|
||||
{
|
||||
HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) begin", curJsModulePath.c_str(),
|
||||
newJsModuleUri.c_str());
|
||||
HILOG_INFO("Search JS module (%{public}s, %{public}s) begin",
|
||||
curJsModulePath.c_str(), newJsModuleUri.c_str());
|
||||
|
||||
std::string newJsModulePath;
|
||||
|
||||
if (curJsModulePath.empty() || newJsModuleUri.empty()) {
|
||||
return newJsModulePath;
|
||||
}
|
||||
|
||||
std::string normalizeUri = newJsModuleUri;
|
||||
std::replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/');
|
||||
|
||||
switch (normalizeUri[0]) {
|
||||
case '.': {
|
||||
newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri);
|
||||
break;
|
||||
}
|
||||
case '@': {
|
||||
newJsModulePath = ParseOhmUri(curJsModulePath, normalizeUri);
|
||||
newJsModulePath = ParseOhmUri(bundleName_, curJsModulePath, normalizeUri);
|
||||
if (newJsModulePath.empty()) {
|
||||
newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri);
|
||||
}
|
||||
@@ -391,21 +53,11 @@ std::string JsModuleSearcher::ParseJsModuleUri(const std::string& curJsModulePat
|
||||
}
|
||||
|
||||
FixExtName(newJsModulePath);
|
||||
HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) => %{public}s end",
|
||||
|
||||
HILOG_INFO("Search JS module (%{public}s, %{public}s) => %{public}s end",
|
||||
curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str());
|
||||
|
||||
return newJsModulePath;
|
||||
}
|
||||
|
||||
bool JsModuleSearcher::GetABCFileBuffer(
|
||||
const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const
|
||||
{
|
||||
std::string newJsModulePath = ParseJsModuleUri(curJsModulePath, newJsModuleUri);
|
||||
|
||||
if (!GetABCFile(hapPath_, newJsModulePath, dest)) {
|
||||
HILOG_ERROR("Get abc file failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
@@ -16,18 +16,13 @@
|
||||
#ifndef OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H
|
||||
#define OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class JsModuleSearcher final {
|
||||
public:
|
||||
explicit JsModuleSearcher(const std::string& bundleName, const std::string& hapPath,
|
||||
const std::string& bundleInstallPath = "/data/storage/el1/bundle/",
|
||||
const std::string& otherBundleInstallPath = "/data/bundles/")
|
||||
: bundleName_(bundleName), hapPath_(hapPath), bundleInstallPath_(bundleInstallPath),
|
||||
otherBundleInstallPath_(otherBundleInstallPath)
|
||||
explicit JsModuleSearcher(const std::string& bundleName) : bundleName_(bundleName)
|
||||
{}
|
||||
~JsModuleSearcher() = default;
|
||||
|
||||
@@ -37,25 +32,9 @@ public:
|
||||
JsModuleSearcher& operator=(JsModuleSearcher&&) = default;
|
||||
|
||||
std::string operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const;
|
||||
bool GetABCFileBuffer(
|
||||
const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const;
|
||||
|
||||
private:
|
||||
static void FixExtName(std::string& path);
|
||||
|
||||
std::string GetInstallPath(const std::string& curJsModulePath, bool module = true) const;
|
||||
std::string MakeNewJsModulePath(const std::string& curJsModulePath, const std::string& newJsModuleUri) const;
|
||||
std::string FindNpmPackageInPath(const std::string& npmPath) const;
|
||||
std::string FindNpmPackageInTopLevel(
|
||||
const std::string& moduleInstallPath, const std::string& npmPackage, size_t start = 0) const;
|
||||
std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage) const;
|
||||
std::string ParseOhmUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const;
|
||||
std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const;
|
||||
|
||||
std::string bundleName_;
|
||||
std::string hapPath_;
|
||||
std::string bundleInstallPath_;
|
||||
std::string otherBundleInstallPath_;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
#include <sys/epoll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "connect_server_manager.h"
|
||||
#include "event_handler.h"
|
||||
#include "hdc_register.h"
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_console_log.h"
|
||||
#include "js_module_searcher.h"
|
||||
#include "js_module_reader.h"
|
||||
#include "js_runtime_utils.h"
|
||||
#include "js_timer.h"
|
||||
#include "js_worker.h"
|
||||
@@ -111,12 +111,17 @@ public:
|
||||
{
|
||||
bool result = false;
|
||||
if (!hapPath.empty()) {
|
||||
std::ostringstream outStreamForABC;
|
||||
if (!GetABCFile(hapPath, path, outStreamForABC)) {
|
||||
std::ostringstream outStream;
|
||||
if (!GetFileBufferFromHap(hapPath, path, outStream)) {
|
||||
HILOG_ERROR("Get abc file failed");
|
||||
return result;
|
||||
}
|
||||
result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; //, (void *)outStreamForABC
|
||||
|
||||
const auto& outStr = outStream.str();
|
||||
std::vector<uint8_t> buffer;
|
||||
buffer.assign(outStr.begin(), outStr.end());
|
||||
|
||||
result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr;
|
||||
} else {
|
||||
result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr;
|
||||
}
|
||||
@@ -189,7 +194,8 @@ private:
|
||||
|
||||
if (!options.preload) {
|
||||
bundleName_ = options.bundleName;
|
||||
panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName, options.hapPath));
|
||||
panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName));
|
||||
panda::JSNApi::SetHostResolveBufferTracker(vm_, JsModuleReader(options.bundleName, options.hapPath));
|
||||
}
|
||||
return JsRuntime::Initialize(options);
|
||||
}
|
||||
@@ -234,46 +240,6 @@ void InitSyscapModule(NativeEngine& engine, NativeObject& globalObject)
|
||||
{
|
||||
BindNativeFunction(engine, globalObject, "canIUse", CanIUse);
|
||||
}
|
||||
|
||||
bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName)
|
||||
{
|
||||
std::string path(codePath);
|
||||
path.append("/").append(modulePath);// phone/./ets/MainAbility6/MainAbility6.abc
|
||||
if (path.length() > PATH_MAX) {
|
||||
HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX);
|
||||
return false;
|
||||
}
|
||||
char resolvedPath[PATH_MAX + 1] = { 0 };
|
||||
if (realpath(path.c_str(), resolvedPath) != nullptr) {
|
||||
fileName = resolvedPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto start = path.find_last_of('/');
|
||||
auto end = path.find_last_of('.');
|
||||
if (end == std::string::npos || end == 0) {
|
||||
HILOG_ERROR("No secondary file path");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pos = path.find_last_of('.', end - 1);
|
||||
if (pos == std::string::npos) {
|
||||
HILOG_ERROR("No secondary file path");
|
||||
return false;
|
||||
}
|
||||
|
||||
path.erase(start + 1, pos - start);
|
||||
HILOG_INFO("Try using secondary file path: %{public}s", path.c_str());
|
||||
|
||||
if (realpath(path.c_str(), resolvedPath) == nullptr) {
|
||||
HILOG_ERROR("Failed to call realpath, errno = %{public}d", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
fileName = resolvedPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
class UvLoopHandler : public AppExecFwk::FileDescriptorListener, public std::enable_shared_from_this<UvLoopHandler> {
|
||||
public:
|
||||
explicit UvLoopHandler(uv_loop_t* uvLoop) : uvLoop_(uvLoop) {}
|
||||
@@ -507,7 +473,7 @@ NativeValue* JsRuntime::LoadJsBundle(const std::string& path, const std::string&
|
||||
}
|
||||
|
||||
std::unique_ptr<NativeReference> JsRuntime::LoadModule(const std::string& moduleName,
|
||||
const std::string& modulePath, bool esmodule, const std::string& hapPath)
|
||||
const std::string& modulePath, const std::string& hapPath, bool esmodule)
|
||||
{
|
||||
HILOG_INFO("JsRuntime::LoadModule(%{public}s, %{public}s, %{public}s)", moduleName.c_str(), modulePath.c_str(),
|
||||
esmodule ? "true" : "false");
|
||||
@@ -566,12 +532,17 @@ bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath)
|
||||
{
|
||||
bool result = false;
|
||||
if (!hapPath.empty()) {
|
||||
std::ostringstream outStreamForABC;
|
||||
if (!GetABCFile(hapPath, path, outStreamForABC)) {
|
||||
std::ostringstream outStream;
|
||||
if (!GetFileBufferFromHap(hapPath, path, outStream)) {
|
||||
HILOG_ERROR("Get abc file failed");
|
||||
return result;
|
||||
}
|
||||
result = nativeEngine_->RunScript(path.c_str()) != nullptr; //, (void *)outStreamForABC
|
||||
|
||||
const auto& outStr = outStream.str();
|
||||
std::vector<uint8_t> buffer;
|
||||
buffer.assign(outStr.begin(), outStr.end());
|
||||
|
||||
result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr;
|
||||
} else {
|
||||
result = nativeEngine_->RunScript(path.c_str()) != nullptr;
|
||||
}
|
||||
|
||||
@@ -15,16 +15,49 @@
|
||||
|
||||
#include "js_runtime_utils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "ability_constants.h"
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_runtime.h"
|
||||
#include "runtime_extractor.h"
|
||||
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
#include <io.h>
|
||||
|
||||
namespace {
|
||||
char* realpath(const char* path, char* resolvedPath)
|
||||
{
|
||||
if (_access(path, 0) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (strcpy_s(resolvedPath, PATH_MAX, path) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return resolvedPath;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
constexpr char EXT_NAME_ABC[] = ".abc";
|
||||
constexpr char EXT_NAME_ETS[] = ".ets";
|
||||
constexpr char EXT_NAME_TS[] = ".ts";
|
||||
constexpr char EXT_NAME_JS[] = ".js";
|
||||
constexpr char PREFIX_BUNDLE[] = "@bundle:";
|
||||
constexpr char PREFIX_MODULE[] = "@module:";
|
||||
constexpr char PREFIX_LOCAL[] = "@local:";
|
||||
constexpr char NPM_PATH_SEGMENT[] = "node_modules";
|
||||
constexpr char NPM_ENTRY_FILE[] = "index.abc";
|
||||
constexpr char NPM_ENTRY_LINK[] = "entry.txt";
|
||||
constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
|
||||
constexpr char OTHER_BUNDLE_INSTALL_PATH[] = "/data/bundles/";
|
||||
|
||||
constexpr size_t MAX_NPM_LEVEL = 1;
|
||||
|
||||
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
|
||||
std::unique_ptr<AsyncTask::ExecuteCallback>&& execute, std::unique_ptr<AsyncTask::CompleteCallback>&& complete,
|
||||
NativeValue** result)
|
||||
@@ -39,14 +72,64 @@ std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, Na
|
||||
return std::make_unique<AsyncTask>(callbackRef, std::move(execute), std::move(complete));
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Help Functions
|
||||
bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen)
|
||||
inline bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen)
|
||||
{
|
||||
return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0));
|
||||
}
|
||||
|
||||
inline bool StringEndWith(const std::string& str, const char* endStr, size_t endStrLen)
|
||||
{
|
||||
size_t len = str.length();
|
||||
return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0));
|
||||
}
|
||||
|
||||
void SplitString(const std::string& str, std::vector<std::string>& out, size_t pos = 0, const char* seps = "\\/")
|
||||
{
|
||||
if (str.empty() || pos >= str.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t startPos = pos;
|
||||
size_t endPos = 0;
|
||||
while ((endPos = str.find_first_of(seps, startPos)) != std::string::npos) {
|
||||
if (endPos > startPos) {
|
||||
out.emplace_back(str.substr(startPos, endPos - startPos));
|
||||
}
|
||||
startPos = endPos + 1;
|
||||
}
|
||||
|
||||
if (startPos < str.length()) {
|
||||
out.emplace_back(str.substr(startPos));
|
||||
}
|
||||
}
|
||||
|
||||
std::string JoinString(const std::vector<std::string>& strs, char sep, size_t startIndex = 0)
|
||||
{
|
||||
std::string out;
|
||||
for (size_t index = startIndex; index < strs.size(); ++index) {
|
||||
if (!strs[index].empty()) {
|
||||
out.append(strs[index]) += sep;
|
||||
}
|
||||
}
|
||||
if (!out.empty()) {
|
||||
out.pop_back();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::string StripString(const std::string& str, const char* charSet = " \t\n\r")
|
||||
{
|
||||
size_t startPos = str.find_first_not_of(charSet);
|
||||
if (startPos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return str.substr(startPos, str.find_last_not_of(charSet) - startPos + 1);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Help Functions
|
||||
NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message)
|
||||
{
|
||||
return engine.CreateError(CreateJsValue(engine, errCode), CreateJsValue(engine, message));
|
||||
@@ -247,10 +330,332 @@ std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, Na
|
||||
std::unique_ptr<AsyncTask::CompleteCallback>(), result);
|
||||
}
|
||||
|
||||
bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest)
|
||||
void FixExtName(std::string& path)
|
||||
{
|
||||
if (path.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringEndWith(path, EXT_NAME_ABC, sizeof(EXT_NAME_ABC) - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringEndWith(path, EXT_NAME_ETS, sizeof(EXT_NAME_ETS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_ETS) - 1), sizeof(EXT_NAME_ETS) - 1);
|
||||
} else if (StringEndWith(path, EXT_NAME_TS, sizeof(EXT_NAME_TS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_TS) - 1), sizeof(EXT_NAME_TS) - 1);
|
||||
} else if (StringEndWith(path, EXT_NAME_JS, sizeof(EXT_NAME_JS) - 1)) {
|
||||
path.erase(path.length() - (sizeof(EXT_NAME_JS) - 1), sizeof(EXT_NAME_JS) - 1);
|
||||
}
|
||||
|
||||
path.append(EXT_NAME_ABC);
|
||||
}
|
||||
|
||||
std::string GetInstallPath(const std::string& curJsModulePath, bool module)
|
||||
{
|
||||
size_t pos = std::string::npos;
|
||||
if (StringStartWith(curJsModulePath, BUNDLE_INSTALL_PATH, std::string(BUNDLE_INSTALL_PATH).length())) {
|
||||
pos = std::string(BUNDLE_INSTALL_PATH).length() - 1;
|
||||
} else {
|
||||
if (!StringStartWith(curJsModulePath, OTHER_BUNDLE_INSTALL_PATH,
|
||||
std::string(OTHER_BUNDLE_INSTALL_PATH).length())) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
pos = curJsModulePath.find('/', std::string(OTHER_BUNDLE_INSTALL_PATH).length());
|
||||
if (pos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
if (module) {
|
||||
pos = curJsModulePath.find('/', pos + 1);
|
||||
if (pos == std::string::npos) {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
return curJsModulePath.substr(0, pos + 1);
|
||||
}
|
||||
|
||||
std::string MakeNewJsModulePath(
|
||||
const std::string& curJsModulePath, const std::string& newJsModuleUri)
|
||||
{
|
||||
std::string moduleInstallPath = GetInstallPath(curJsModulePath, true);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::vector<std::string> pathVector;
|
||||
SplitString(curJsModulePath, pathVector, moduleInstallPath.length());
|
||||
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Remove file name, reserve only dir name
|
||||
pathVector.pop_back();
|
||||
|
||||
std::vector<std::string> relativePathVector;
|
||||
SplitString(newJsModuleUri, relativePathVector);
|
||||
|
||||
for (auto& value : relativePathVector) {
|
||||
if (value == ".") {
|
||||
continue;
|
||||
} else if (value == "..") {
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
pathVector.pop_back();
|
||||
} else {
|
||||
pathVector.emplace_back(std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
std::string jsModulePath = moduleInstallPath + JoinString(pathVector, '/');
|
||||
FixExtName(jsModulePath);
|
||||
if (jsModulePath.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (realpath(jsModulePath.c_str(), path) != nullptr) {
|
||||
return std::string(path);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string FindNpmPackageInPath(const std::string& npmPath)
|
||||
{
|
||||
std::string fileName = npmPath + "/" + NPM_ENTRY_FILE;
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (fileName.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
if (realpath(fileName.c_str(), path) != nullptr) {
|
||||
return path;
|
||||
}
|
||||
|
||||
fileName = npmPath + "/" + NPM_ENTRY_LINK;
|
||||
if (fileName.size() >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
if (realpath(fileName.c_str(), path) == nullptr) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::ifstream stream(path, std::ios::ate);
|
||||
if (!stream.is_open()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto fileLen = stream.tellg();
|
||||
if (fileLen >= PATH_MAX) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
stream.seekg(0);
|
||||
stream.read(path, fileLen);
|
||||
path[fileLen] = '\0';
|
||||
return npmPath + '/' + StripString(path);
|
||||
}
|
||||
|
||||
std::string FindNpmPackageInTopLevel(
|
||||
const std::string& moduleInstallPath, const std::string& npmPackage, size_t start)
|
||||
{
|
||||
for (size_t level = start; level <= MAX_NPM_LEVEL; ++level) {
|
||||
std::string path = moduleInstallPath + NPM_PATH_SEGMENT + '/' + std::to_string(level) + '/' + npmPackage;
|
||||
path = FindNpmPackageInPath(path);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage)
|
||||
{
|
||||
std::string newJsModulePath = MakeNewJsModulePath(curJsModulePath, npmPackage);
|
||||
if (!newJsModulePath.empty()) {
|
||||
return newJsModulePath;
|
||||
}
|
||||
std::string moduleInstallPath = GetInstallPath(curJsModulePath);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
std::vector<std::string> pathVector;
|
||||
SplitString(curJsModulePath, pathVector, moduleInstallPath.length());
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (pathVector[0] != NPM_PATH_SEGMENT) {
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage);
|
||||
}
|
||||
|
||||
// Remove file name, reserve only dir name
|
||||
pathVector.pop_back();
|
||||
|
||||
// Find npm package until reach top level npm path such as 'node_modules/0',
|
||||
// so there must be 2 element in vector
|
||||
while (pathVector.size() > 2) {
|
||||
std::string path =
|
||||
moduleInstallPath + JoinString(pathVector, '/') + '/' + NPM_PATH_SEGMENT + '/' + npmPackage;
|
||||
path = FindNpmPackageInPath(path);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
pathVector.pop_back();
|
||||
}
|
||||
|
||||
char* p = nullptr;
|
||||
size_t index = std::strtoul(pathVector.back().c_str(), &p, 10);
|
||||
if (p == nullptr || *p != '\0') {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage, index);
|
||||
}
|
||||
|
||||
std::string ParseOhmUri(
|
||||
const std::string originBundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri)
|
||||
{
|
||||
std::string moduleInstallPath;
|
||||
std::vector<std::string> pathVector;
|
||||
size_t index = 0;
|
||||
|
||||
if (StringStartWith(newJsModuleUri, PREFIX_BUNDLE, sizeof(PREFIX_BUNDLE) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_BUNDLE) - 1);
|
||||
|
||||
// Uri should have atleast 3 segments
|
||||
if (pathVector.size() < 3) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const auto& bundleName = pathVector[index++];
|
||||
if (bundleName == originBundleName) {
|
||||
moduleInstallPath = std::string(BUNDLE_INSTALL_PATH);
|
||||
} else {
|
||||
moduleInstallPath = std::string(OTHER_BUNDLE_INSTALL_PATH);
|
||||
moduleInstallPath.append(bundleName).append("/");
|
||||
}
|
||||
moduleInstallPath.append(pathVector[index++]).append("/");
|
||||
} else if (StringStartWith(newJsModuleUri, PREFIX_MODULE, sizeof(PREFIX_MODULE) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_MODULE) - 1);
|
||||
|
||||
// Uri should have atleast 2 segments
|
||||
if (pathVector.size() < 2) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
moduleInstallPath = GetInstallPath(curJsModulePath, false);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
moduleInstallPath.append(pathVector[index++]).append("/");
|
||||
} else if (StringStartWith(newJsModuleUri, PREFIX_LOCAL, sizeof(PREFIX_LOCAL) - 1)) {
|
||||
SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_LOCAL) - 1);
|
||||
|
||||
if (pathVector.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
moduleInstallPath = GetInstallPath(curJsModulePath);
|
||||
if (moduleInstallPath.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (pathVector[index] != NPM_PATH_SEGMENT) {
|
||||
return moduleInstallPath + JoinString(pathVector, '/', index);
|
||||
}
|
||||
|
||||
return FindNpmPackageInTopLevel(moduleInstallPath, JoinString(pathVector, '/', index + 1));
|
||||
}
|
||||
|
||||
bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName)
|
||||
{
|
||||
std::string path(codePath);
|
||||
path.append("/").append(modulePath);
|
||||
if (path.length() > PATH_MAX) {
|
||||
HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX);
|
||||
return false;
|
||||
}
|
||||
char resolvedPath[PATH_MAX + 1] = { 0 };
|
||||
if (realpath(path.c_str(), resolvedPath) != nullptr) {
|
||||
fileName = resolvedPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto start = path.find_last_of('/');
|
||||
auto end = path.find_last_of('.');
|
||||
if (end == std::string::npos || end == 0) {
|
||||
HILOG_ERROR("No secondary file path");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pos = path.find_last_of('.', end - 1);
|
||||
if (pos == std::string::npos) {
|
||||
HILOG_ERROR("No secondary file path");
|
||||
return false;
|
||||
}
|
||||
|
||||
path.erase(start + 1, pos - start);
|
||||
HILOG_INFO("Try using secondary file path: %{public}s", path.c_str());
|
||||
|
||||
if (realpath(path.c_str(), resolvedPath) == nullptr) {
|
||||
HILOG_ERROR("Failed to call realpath, errno = %{public}d", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
fileName = resolvedPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetOhmUri(const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo)
|
||||
{
|
||||
std::string ohmUri;
|
||||
if (!abilityInfo) {
|
||||
HILOG_ERROR("GetOhmUri::AbilityInfo is nullptr");
|
||||
return ohmUri;
|
||||
}
|
||||
|
||||
std::string srcPath(abilityInfo->package);
|
||||
if (!abilityInfo->isModuleJson) {
|
||||
/* temporary compatibility api8 + config.json */
|
||||
srcPath.append("/assets/js/");
|
||||
if (!abilityInfo->srcPath.empty()) {
|
||||
srcPath.append(abilityInfo->srcPath);
|
||||
}
|
||||
srcPath.append("/").append(abilityInfo->name).append(".abc");
|
||||
} else {
|
||||
if (abilityInfo->srcEntrance.empty()) {
|
||||
HILOG_ERROR("GetOhmUri::AbilityInfo srcEntrance is empty");
|
||||
return ohmUri;
|
||||
}
|
||||
srcPath.append("/");
|
||||
srcPath.append(abilityInfo->srcEntrance);
|
||||
srcPath.erase(srcPath.rfind("."));
|
||||
srcPath.append(".abc");
|
||||
}
|
||||
HILOG_DEBUG("GetOhmUri::JsAbility srcPath is %{public}s", srcPath.c_str());
|
||||
|
||||
if (!MakeFilePath(Constants::LOCAL_CODE_PATH, srcPath, ohmUri)) {
|
||||
HILOG_ERROR("GetOhmUri::Failed to make module file path: %{private}s", srcPath.c_str());
|
||||
}
|
||||
|
||||
return ohmUri;
|
||||
}
|
||||
|
||||
bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest)
|
||||
{
|
||||
if (hapPath.empty() || srcPath.empty()) {
|
||||
HILOG_ERROR("GetABCFile::hapPath or srcPath is nullptr");
|
||||
HILOG_ERROR("GetFileBufferFromHap::hapPath or srcPath is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -265,19 +670,65 @@ bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ost
|
||||
}
|
||||
RuntimeExtractor runtimeExtractor(loadPath);
|
||||
if (!runtimeExtractor.Init()) {
|
||||
HILOG_ERROR("GetABCFile::Runtime extractor init failed");
|
||||
HILOG_ERROR("GetFileBufferFromHap::Runtime extractor init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR));
|
||||
std::string relativePath = std::regex_replace(srcPath, srcPattern, "");
|
||||
relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1);
|
||||
if (!runtimeExtractor.ExtractABCFile(relativePath, dest)) {
|
||||
HILOG_ERROR("GetABCFile::Extract abc file failed");
|
||||
if (!runtimeExtractor.ExtractByName(relativePath, dest)) {
|
||||
HILOG_ERROR("GetFileBufferFromHap::Extract abc file failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector<std::string>& assetList)
|
||||
{
|
||||
if (hapPath.empty() || srcPath.empty()) {
|
||||
HILOG_ERROR("GetFileListFromHap::hapPath or srcPath is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string loadPath;
|
||||
if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) {
|
||||
std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR));
|
||||
loadPath = std::regex_replace(hapPath, hapPattern, "");
|
||||
loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) +
|
||||
loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1);
|
||||
} else {
|
||||
loadPath = hapPath;
|
||||
}
|
||||
RuntimeExtractor runtimeExtractor(loadPath);
|
||||
if (!runtimeExtractor.Init()) {
|
||||
HILOG_ERROR("GetFileListFromHap::Runtime extractor init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR));
|
||||
std::string relativePath = std::regex_replace(srcPath, srcPattern, "");
|
||||
relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1);
|
||||
|
||||
std::vector<std::string> fileList;
|
||||
if (!runtimeExtractor.GetZipFileNames(fileList)) {
|
||||
HILOG_ERROR("GetFileListFromHap::Get file list failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::regex replacePattern(relativePath);
|
||||
for (auto value : fileList) {
|
||||
if (StringStartWith(value, relativePath.c_str(), sizeof(relativePath.c_str()) - 1)) {
|
||||
std::string realpath = std::regex_replace(value, replacePattern, "");
|
||||
if (realpath.find(Constants::FILE_SEPARATOR) != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
assetList.emplace_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -28,11 +28,5 @@ RuntimeExtractor::~RuntimeExtractor()
|
||||
{
|
||||
HILOG_DEBUG("RuntimeExtractor destroyed");
|
||||
}
|
||||
|
||||
bool RuntimeExtractor::ExtractABCFile(const std::string& srcPath, std::ostream &dest) const
|
||||
{
|
||||
HILOG_DEBUG("%{public}s: hapPath is %{public}s", __func__, srcPath.c_str());
|
||||
return AppExecFwk::BaseExtractor::ExtractByName(srcPath, dest);
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -37,6 +37,7 @@ ohos_shared_library("runtime") {
|
||||
"${ability_runtime_native_path}/runtime/hdc_register.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_console_log.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_data_struct_converter.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_module_reader.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_module_searcher.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_runtime.cpp",
|
||||
"${ability_runtime_native_path}/runtime/js_runtime_utils.cpp",
|
||||
@@ -53,11 +54,14 @@ ohos_shared_library("runtime") {
|
||||
public_configs = [ ":runtime_public_config" ]
|
||||
|
||||
deps = [
|
||||
":runtime_extractor",
|
||||
"//arkcompiler/ets_runtime:libark_jsruntime",
|
||||
"//foundation/arkui/napi:ace_napi_ark",
|
||||
":runtime_extractor"
|
||||
]
|
||||
|
||||
public_deps =
|
||||
[ "${bundlefwk_inner_api_path}/appexecfwk_base:appexecfwk_base" ]
|
||||
|
||||
external_deps = [
|
||||
"ability_base:base",
|
||||
"ability_base:configuration",
|
||||
@@ -65,7 +69,6 @@ ohos_shared_library("runtime") {
|
||||
"ability_base:zuri",
|
||||
"ability_runtime:ability_manager",
|
||||
"ability_runtime:app_manager",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"eventhandler:libeventhandler",
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"napi:ace_napi",
|
||||
@@ -97,26 +100,18 @@ ohos_shared_library("runtime") {
|
||||
ohos_source_set("runtime_extractor") {
|
||||
include_dirs = [ "include" ]
|
||||
|
||||
sources = [
|
||||
"${ability_runtime_native_path}/runtime/runtime_extractor.cpp",
|
||||
]
|
||||
sources = [ "${ability_runtime_native_path}/runtime/runtime_extractor.cpp" ]
|
||||
|
||||
configs = [
|
||||
"${ability_runtime_services_path}/common:common_config",
|
||||
]
|
||||
configs = [ "${ability_runtime_services_path}/common:common_config" ]
|
||||
|
||||
cflags = []
|
||||
if (target_cpu == "arm") {
|
||||
cflags += [ "-DBINDER_IPC_32BIT" ]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
"${bundlefwk_services_path}/bundlemgr:parser_common",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
]
|
||||
public_deps = [ "${bundlefwk_services_path}/bundlemgr:parser_common" ]
|
||||
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
|
||||
subsystem_name = "ability"
|
||||
part_name = "ability_runtime"
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
}
|
||||
|
||||
std::unique_ptr<NativeReference> LoadModule(const std::string& moduleName,
|
||||
const std::string& modulePath, bool esmodule = false, const std::string& hapPath = nullptr);
|
||||
const std::string& modulePath, const std::string& hapPath, bool esmodule = false);
|
||||
std::unique_ptr<NativeReference> LoadSystemModule(
|
||||
const std::string& moduleName, NativeValue* const* argv = nullptr, size_t argc = 0);
|
||||
void PostTask(const std::function<void()>& task, const std::string& name, int64_t delayTime);
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
void NotifyApplicationState(bool isBackground) override;
|
||||
|
||||
bool RunSandboxScript(const std::string& path, const std::string& hapPath);
|
||||
virtual bool RunScript(const std::string& path, const std::string& hapPath = nullptr) = 0;
|
||||
virtual bool RunScript(const std::string& path, const std::string& hapPath) = 0;
|
||||
|
||||
void PreloadSystemModule(const std::string& moduleName) override;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "native_engine/native_engine.h"
|
||||
|
||||
#include "ability_info.h"
|
||||
#include "js_runtime.h"
|
||||
|
||||
namespace OHOS {
|
||||
@@ -112,7 +113,6 @@ NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector<T>& data)
|
||||
return arrayValue;
|
||||
}
|
||||
|
||||
bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen);
|
||||
NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string());
|
||||
void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name, NativeCallback func);
|
||||
void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter);
|
||||
@@ -187,7 +187,20 @@ std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, Na
|
||||
std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
|
||||
nullptr_t, nullptr_t, NativeValue** result);
|
||||
|
||||
bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest);
|
||||
void FixExtName(std::string& path);
|
||||
std::string GetInstallPath(const std::string& curJsModulePath, bool module = true);
|
||||
std::string MakeNewJsModulePath(const std::string& curJsModulePath, const std::string& newJsModuleUri);
|
||||
std::string FindNpmPackageInPath(const std::string& npmPath);
|
||||
std::string FindNpmPackageInTopLevel(
|
||||
const std::string& moduleInstallPath, const std::string& npmPackage, size_t start = 0);
|
||||
std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage);
|
||||
std::string ParseOhmUri(
|
||||
const std::string bundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri);
|
||||
std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri);
|
||||
bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName);
|
||||
std::string GetOhmUri(const std::shared_ptr<AppExecFwk::AbilityInfo> &abilityInfo);
|
||||
bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest);
|
||||
bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector<std::string>& assetList);
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022 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
|
||||
@@ -24,14 +24,6 @@ class RuntimeExtractor : public AppExecFwk::BaseExtractor {
|
||||
public:
|
||||
explicit RuntimeExtractor(const std::string &source);
|
||||
virtual ~RuntimeExtractor() override;
|
||||
|
||||
/**
|
||||
* @brief Extract the abc file of a hap to dest stream.
|
||||
* @param srcPath Indicates the src path of the abc file in hap.
|
||||
* @param dest Indicates the obtained std::ostream object.
|
||||
* @return Returns true if the Profile is successfully extracted; returns false otherwise.
|
||||
*/
|
||||
bool ExtractABCFile(const std::string& srcPath, std::ostream &dest) const;
|
||||
};
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
||||
|
||||
Reference in New Issue
Block a user