* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ani_js_initialize.h"
#include "ani_task.h"
#include <cerrno>
#include <fcntl.h>
#include <securec.h>
#include <sys/stat.h>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <new>
#include <regex>
#include <string>
#include <system_error>
#include "ani_utils.h"
#include "log.h"
#include "net_conn_client.h"
#include "parameter.h"
#include "request_common.h"
#include "request_manager.h"
#include "sys_event.h"
static const std::string AREA1 = "/data/storage/el1/base";
static const std::string AREA2 = "/data/storage/el2/base";
static const std::string AREA5 = "/data/storage/el5/base";
static constexpr uint32_t MAX_UPLOAD_ON15_FILES = 100;
using namespace OHOS::AniUtil;
namespace OHOS::Request {
static std::string GetErrnoAppendMessage(int32_t errNum)
{
switch (errNum) {
case ENOENT:
return ", File not found";
case EACCES:
return ", Permission denied";
case EISDIR:
return ", Path is a directory, not a file";
case ENOSPC:
return ", Insufficient storage space on device";
case EROFS:
return ", Read-only file system";
default:
return "";
}
}
bool IsPathValid(const std::string &filePath)
{
auto path = filePath.substr(0, filePath.rfind('/'));
char resolvedPath[PATH_MAX] = { 0 };
if (path.length() > PATH_MAX || realpath(path.c_str(), resolvedPath) == nullptr
|| strncmp(resolvedPath, path.c_str(), path.length()) != 0) {
REQUEST_HILOGE("invalid file path!");
return false;
}
return true;
}
std::shared_ptr<OHOS::AbilityRuntime::Context> JsInitialize::GetContext(ani_env *env, ani_object object)
{
if (env == nullptr) {
REQUEST_HILOGE("env is nullptr");
return nullptr;
}
ani_long nativeContextLong;
ani_status status = env->Object_GetFieldByName_Long(object, "nativeContext", &nativeContextLong);
if (status != ANI_OK) {
REQUEST_HILOGE("Object_GetField_Long failed, status : %{public}d", status);
return nullptr;
}
REQUEST_HILOGI("in GetStageModeContext nativeContext is %{public}lld.", static_cast<long long>(nativeContextLong));
auto weakContext = reinterpret_cast<std::weak_ptr<OHOS::AbilityRuntime::Context>*>(nativeContextLong);
if (weakContext == nullptr) {
REQUEST_HILOGE("into GetStageModeContext, weakContext is nullptr");
}
auto ret = weakContext != nullptr ? weakContext->lock() : nullptr;
if (ret == nullptr) {
REQUEST_HILOGE("into GetStageModeContext, ret is nullptr");
return ret;
}
REQUEST_HILOGI("into GetStageModeContext, ret is not nullptr");
return ret;
}
bool JsInitialize::GetAppBaseDir(std::string &baseDir)
{
auto context = AbilityRuntime::Context::GetApplicationContext();
if (context == nullptr) {
REQUEST_HILOGE("AppContext is null.");
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_02, "AppContext is null");
return false;
}
baseDir = context->GetBaseDir();
if (baseDir.empty()) {
REQUEST_HILOGE("Base dir not found.");
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_07, "Base dir not found");
return false;
}
return true;
}
bool JsInitialize::CheckFilePath(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config, ExceptionError &error)
{
if (config.action == Action::DOWNLOAD) {
if (!CheckDownloadFile(context, config, error)) {
SysEventLog::SendSysEventLog(STATISTIC_EVENT, APP_ERROR_00, config.bundleName, "", error.errInfo);
return false;
}
} else {
if (!CheckUploadFiles(context, config, error)) {
SysEventLog::SendSysEventLog(STATISTIC_EVENT, APP_ERROR_01, config.bundleName, "", error.errInfo);
return false;
}
std::string filePath = context->GetCacheDir();
if (!CheckUploadBodyFiles(filePath, config, error)) {
SysEventLog::SendSysEventLog(STATISTIC_EVENT, APP_ERROR_02, config.bundleName, "", error.errInfo);
return false;
}
}
if (!AniTask::SetDirsPermission(config.certsPath)) {
error.code = E_FILE_IO;
error.errInfo = "set files of directors permission fail";
SysEventLog::SendSysEventLog(FAULT_EVENT, TASK_FAULT_02, config.bundleName, "", error.errInfo);
return false;
}
return true;
}
bool JsInitialize::CheckUploadBodyFiles(const std::string &filePath, Config &config, ExceptionError &error)
{
size_t len = config.files.size();
if (config.multipart) {
len = 1;
}
for (size_t i = 0; i < len; i++) {
if (filePath.empty()) {
REQUEST_HILOGE("internal to cache error");
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, UploadBodyFiles error empty path";
return false;
}
auto now = std::chrono::high_resolution_clock::now();
auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
std::string path = filePath + "/tmp_body_" + std::to_string(i) + "_" + std::to_string(timestamp);
if (!IsPathValid(path)) {
REQUEST_HILOGE("Upload IsPathValid error");
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, UploadBodyFiles error fail path";
return false;
}
FILE *bodyFile = fopen(path.c_str(), "w+");
if (bodyFile == NULL) {
error.code = E_FILE_IO;
error.errInfo = "UploadBodyFiles failed to open file errno " + std::to_string(errno)
+ GetErrnoAppendMessage(errno);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_00, config.bundleName, "", error.errInfo);
return false;
}
int32_t ret = chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (ret != 0) {
REQUEST_HILOGE("body chmod fail: %{public}d", ret);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_01, config.bundleName, "", std::to_string(ret));
};
bool setRes = AniTask::SetPathPermission(path);
int32_t retClose = fclose(bodyFile);
if (retClose != 0) {
REQUEST_HILOGE("upload body fclose fail: %{public}d", ret);
SysEventLog::SendSysEventLog(
FAULT_EVENT, STANDARD_FAULT_02, config.bundleName, "", std::to_string(retClose));
}
if (!setRes) {
error.code = E_FILE_IO;
error.errInfo = "UploadBodyFiles set body path permission fail";
return false;
}
config.bodyFileNames.push_back(path);
}
return true;
}
bool JsInitialize::CheckPathIsFile(const std::string &path, ExceptionError &error)
{
std::error_code err;
if (!std::filesystem::exists(path, err)) {
error.code = E_FILE_IO;
error.errInfo = "Path not exists: " + err.message();
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_03, error.errInfo);
return false;
}
if (std::filesystem::is_directory(path, err)) {
error.code = E_FILE_IO;
error.errInfo = "Path not File: " + err.message();
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_04, error.errInfo);
return false;
}
return true;
}
bool JsInitialize::GetFdDownload(const std::string &path, const Config &config, ExceptionError &error)
{
if (JsInitialize::FindDir(path)) {
if (config.firstInit && !config.overwrite) {
error.code = config.version == Version::API10 ? E_FILE_IO : E_FILE_PATH;
error.errInfo = "GetFd File exists and other error, set overwrite=true to replace";
SysEventLog::SendSysEventLog(STATISTIC_EVENT, APP_ERROR_00, config.bundleName, "", error.errInfo);
return false;
}
}
FILE *file = NULL;
if (!IsPathValid(path)) {
REQUEST_HILOGE("GetFdDownload IsPathValid error");
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, GetFdDownload error fail path";
return false;
}
if (config.firstInit) {
file = fopen(path.c_str(), "w+");
} else {
file = fopen(path.c_str(), "a+");
}
if (file == NULL) {
error.code = E_FILE_IO;
error.errInfo = "GetFd failed to open file errno " + std::to_string(errno)
+ GetErrnoAppendMessage(errno);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_00, config.bundleName, "", error.errInfo);
return false;
}
int32_t ret = chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (ret != 0) {
REQUEST_HILOGE("download file chmod fail: %{public}d", ret);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_01, config.bundleName, "", std::to_string(ret));
};
int32_t retClose = fclose(file);
if (retClose != 0) {
REQUEST_HILOGE("download fclose fail: %{public}d", ret);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_02, config.bundleName, "", std::to_string(retClose));
}
return true;
}
bool JsInitialize::InterceptData(const std::string &str, const std::string &in, std::string &out)
{
std::size_t position = in.find_last_of(str);
if (position == std::string::npos || position + 1 >= in.size()) {
return false;
}
out = std::string(in, position + 1);
return true;
}
bool JsInitialize::GetFdUpload(const std::string &path, const Config &config, ExceptionError &error)
{
if (!JsInitialize::CheckPathIsFile(path, error)) {
error.code = config.version == Version::API10 ? E_FILE_IO : E_FILE_PATH;
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_03, config.bundleName, "", error.errInfo);
return false;
}
if (!IsPathValid(path)) {
REQUEST_HILOGE("GetFdUpload IsPathValid error");
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, GetFdUpload error fail path";
return false;
}
FILE *file = fopen(path.c_str(), "r");
if (file == NULL) {
error.code = config.version == Version::API10 ? E_FILE_IO : E_FILE_PATH;
error.errInfo = "GetFd failed to open file errno " + std::to_string(errno)
+ GetErrnoAppendMessage(errno);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_00, config.bundleName, "", error.errInfo);
return false;
}
REQUEST_HILOGD("upload file fopen ok");
int32_t ret = chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (ret != 0) {
REQUEST_HILOGE("upload file chmod fail: %{public}d", ret);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_01, config.bundleName, "", std::to_string(ret));
}
int32_t retClose = fclose(file);
if (retClose != 0) {
REQUEST_HILOGE("upload fclose fail: %{public}d", ret);
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_02, config.bundleName, "", std::to_string(retClose));
}
return true;
}
bool JsInitialize::GetInternalPath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
std::string &path, std::string &errInfo)
{
std::string fileName;
std::string pattern = "internal://cache/";
size_t pos = path.find(pattern);
if (pos != 0) {
fileName = path;
} else {
fileName = path.substr(pattern.size(), path.size());
}
REQUEST_HILOGE("11 fileName %{public}s", fileName.c_str());
if (fileName.empty()) {
errInfo = "Parameter verification failed, GetInternalPath failed, fileName is empty";
return false;
}
path = context->GetCacheDir();
if (path.empty()) {
REQUEST_HILOGE("internal to cache error");
errInfo = "Parameter verification failed, GetInternalPath failed, cache path is empty";
return false;
}
path += "/" + fileName;
if (!IsPathValid(path)) {
REQUEST_HILOGE("IsPathValid error %{public}s", path.c_str());
errInfo = "Parameter verification failed, GetInternalPath failed, filePath is not valid";
return false;
}
return true;
}
std::string GetHostnameFromURL(const std::string &url)
{
if (url.empty()) {
return "";
}
std::string delimiter = "://";
std::string tempUrl = url;
std::replace(tempUrl.begin(), tempUrl.end(), '\\', '/');
size_t posStart = tempUrl.find(delimiter);
if (posStart != std::string::npos) {
posStart += delimiter.length();
} else {
posStart = 0;
}
size_t notSlash = tempUrl.find_first_not_of('/', posStart);
if (notSlash != std::string::npos) {
posStart = notSlash;
}
size_t posEnd = std::min({ tempUrl.find(':', posStart), tempUrl.find('/', posStart), tempUrl.find('?', posStart) });
if (posEnd != std::string::npos) {
return tempUrl.substr(posStart, posEnd - posStart);
}
return tempUrl.substr(posStart);
}
bool JsInitialize::CheckUserFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
const Config &config, FileSpec &file, ExceptionError &error)
{
if (config.mode != Mode::FOREGROUND) {
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, user file can only for Mode::FOREGROUND";
return false;
}
std::shared_ptr<Uri> uri = std::make_shared<Uri>(file.uri);
std::shared_ptr<AppExecFwk::DataAbilityHelper> dataAbilityHelper =
AppExecFwk::DataAbilityHelper::Creator(context, uri);
if (dataAbilityHelper == nullptr) {
REQUEST_HILOGE("dataAbilityHelper null");
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, dataAbilityHelper null";
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_07, config.bundleName, "", error.errInfo);
return false;
}
file.fd = dataAbilityHelper->OpenFile(*uri, "r");
if (file.fd < 0) {
REQUEST_HILOGE("Failed to open user file, fd: %{public}d", file.fd);
error.code = E_FILE_IO;
error.errInfo = "Failed to open user file, errno " + std::to_string(errno)
+ GetErrnoAppendMessage(errno);
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_09, config.bundleName, "", error.errInfo);
return false;
}
StandardizeFileSpec(file);
return true;
}
bool JsInitialize::CheckUploadFiles(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config, ExceptionError &error)
{
int32_t sdkVersion = GetSdkApiVersion();
constexpr const int32_t uploadVersion = 15;
if (config.version == Version::API10 && sdkVersion >= uploadVersion
&& config.files.size() > MAX_UPLOAD_ON15_FILES) {
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, upload by multipart file so many";
return false;
}
for (auto &file : config.files) {
if (IsUserFile(file.uri)) {
file.isUserFile = true;
if (config.version == Version::API9) {
error.code = E_PARAMETER_CHECK;
error.errInfo = "Parameter verification failed, user file can only for request.agent.";
return false;
}
if (!CheckUserFileSpec(context, config, file, error)) {
return false;
}
StandardizeFileSpec(file);
continue;
}
if (!CheckUploadFileSpec(context, config, file, error)) {
return false;
}
}
return true;
}
bool JsInitialize::CheckUploadFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config,
FileSpec &file, ExceptionError &error)
{
file.isUserFile = false;
std::string path = file.uri;
if (config.version == Version::API9) {
if (!GetInternalPath(context, config, path, error.errInfo)) {
error.code = E_PARAMETER_CHECK;
return false;
}
} else {
std::vector<std::string> pathVec;
if (!GetSandboxPath(context, config, path, pathVec, error.errInfo)) {
error.code = E_PARAMETER_CHECK;
return false;
}
}
REQUEST_HILOGI("CheckUploadFileSpec path: %{public}s", path.c_str());
file.uri = path;
if (!GetFdUpload(path, config, error)) {
return false;
}
if (!AniTask::SetPathPermission(file.uri)) {
error.code = E_FILE_IO;
error.errInfo = "set path permission fail, please check file access permissions";
return false;
}
StandardizeFileSpec(file);
return true;
}
bool JsInitialize::CheckDownloadFile(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config, ExceptionError &error)
{
if (config.version == Version::API9) {
std::string path = config.saveas;
if (config.saveas.find('/') == 0) {
} else if (!GetInternalPath(context, config, path, error.errInfo)) {
error.code = E_PARAMETER_CHECK;
return false;
}
config.saveas = path;
} else {
if (!CheckDownloadFilePath(context, config, error.errInfo)) {
error.code = E_PARAMETER_CHECK;
return false;
}
}
FileSpec file = { .uri = config.saveas, .isUserFile = false };
StandardizeFileSpec(file);
config.files.push_back(file);
if (!GetFdDownload(file.uri, config, error)) {
return false;
}
if (!AniTask::SetPathPermission(config.saveas)) {
error.code = E_FILE_IO;
error.errInfo = "set path permission fail, download, please check file access permissions";
return false;
}
return true;
}
bool JsInitialize::CheckDownloadFilePath(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config, std::string &errInfo)
{
std::string path = config.saveas;
std::vector<std::string> pathVec;
if (!GetSandboxPath(context, config, path, pathVec, errInfo)) {
return false;
}
pathVec.pop_back();
if (!JsInitialize::CreateDirs(pathVec)) {
REQUEST_HILOGE("CreateDirs Err");
errInfo = "Parameter verification failed, this is fail saveas path";
return false;
}
config.saveas = path;
return true;
}
bool JsInitialize::CreateDirs(const std::vector<std::string> &pathDirs)
{
std::string path;
std::error_code err;
for (auto elem : pathDirs) {
path += "/" + elem;
if (std::filesystem::exists(path, err)) {
continue;
}
err.clear();
if (!std::filesystem::create_directory(path, err)) {
REQUEST_HILOGE("Create Dir Err: %{public}d, %{public}s", err.value(), err.message().c_str());
SysEventLog::SendSysEventLog(FAULT_EVENT, STANDARD_FAULT_05, err.message());
return false;
}
}
return true;
}
bool JsInitialize::FindDir(const std::string &pathDir)
{
std::error_code err;
return std::filesystem::exists(pathDir, err);
}
bool JsInitialize::IsUserFile(const std::string &path)
{
return path.find("file://docs/") == 0 || path.find("file://media/") == 0;
}
void JsInitialize::StandardizeFileSpec(FileSpec &file)
{
if (file.filename.empty()) {
InterceptData("/", file.uri, file.filename);
}
if (!file.hasContentType) {
InterceptData(".", file.filename, file.type);
}
if (file.name.empty()) {
file.name = "file";
}
return;
}
bool JsInitialize::GetSandboxPath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
std::string &path, std::vector<std::string> &pathVec, std::string &errInfo)
{
if (!StandardizePath(context, config, path)) {
REQUEST_HILOGE("StandardizePath Err");
errInfo = "Parameter verification failed, GetSandboxPath failed, StandardizePath fail";
return false;
};
if (!WholeToNormal(path, pathVec) || pathVec.empty()) {
REQUEST_HILOGE("WholeToNormal Err");
errInfo = "Parameter verification failed, GetSandboxPath failed, WholeToNormal path fail";
return false;
};
std::string baseDir;
if (!CheckBelongAppBaseDir(path, baseDir)) {
REQUEST_HILOGE("CheckBelongAppBaseDir Err");
errInfo = "Parameter verification failed, GetSandboxPath failed, path not belong app base dir";
return false;
};
return true;
}
bool JsInitialize::StandardizePath(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config, std::string &path)
{
std::string WHOLE_PREFIX = "/";
std::string FILE_PREFIX = "file://";
std::string INTERNAL_PREFIX = "internal://";
std::string CURRENT_PREFIX = "./";
if (path.find(WHOLE_PREFIX) == 0) {
return true;
}
if (path.find(FILE_PREFIX) == 0) {
path.erase(0, FILE_PREFIX.size());
return FileToWhole(context, config, path);
}
if (path.find(INTERNAL_PREFIX) == 0) {
path.erase(0, INTERNAL_PREFIX.size());
return BaseToWhole(context, path);
}
if (path.find(CURRENT_PREFIX) == 0) {
path.erase(0, CURRENT_PREFIX.size());
return CacheToWhole(context, path);
}
return CacheToWhole(context, path);
}
bool JsInitialize::BaseToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, std::string &path)
{
std::string base = context->GetBaseDir();
if (base.empty()) {
REQUEST_HILOGE("GetBaseDir error.");
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_06, "GetCacheDir error");
return false;
}
path = base + "/" + path;
return true;
}
bool JsInitialize::CacheToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, std::string &path)
{
std::string cache = context->GetCacheDir();
if (cache.empty()) {
REQUEST_HILOGE("GetCacheDir error.");
SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_05, "GetCacheDir error");
return false;
}
path = cache + "/" + path;
return true;
}
bool JsInitialize::FileToWhole(
const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config, std::string &path)
{
std::string bundleName = path.substr(0, path.find("/"));
if (bundleName != config.bundleName) {
REQUEST_HILOGE("path bundleName error.");
return false;
}
path.erase(0, bundleName.size());
return true;
}
bool JsInitialize::WholeToNormal(std::string &path, std::vector<std::string> &out)
{
std::string normalPath;
std::vector<std::string> elems;
StringSplit(path, '/', elems);
if (!PathVecToNormal(elems, out)) {
return false;
}
for (auto elem : out) {
normalPath += "/" + elem;
}
path = normalPath;
return true;
}
bool JsInitialize::PathVecToNormal(const std::vector<std::string> &in, std::vector<std::string> &out)
{
for (auto elem : in) {
if (elem == "..") {
if (out.size() > 0) {
out.pop_back();
} else {
return false;
}
} else {
out.push_back(elem);
}
}
return true;
}
void JsInitialize::StringSplit(const std::string &str, const char delim, std::vector<std::string> &elems)
{
std::stringstream stream(str);
std::string item;
while (std::getline(stream, item, delim)) {
if (!item.empty()) {
elems.push_back(item);
}
}
return;
}
void JsInitialize::StringTrim(std::string &str)
{
if (str.empty()) {
return;
}
str.erase(0, str.find_first_not_of(" "));
str.erase(str.find_last_not_of(" ") + 1);
return;
}
bool JsInitialize::CheckBelongAppBaseDir(const std::string &filepath, std::string &baseDir)
{
if (!JsInitialize::GetAppBaseDir(baseDir)) {
return false;
}
if ((filepath.find(AREA1) == 0) || filepath.find(AREA2) == 0 || filepath.find(AREA5) == 0) {
return true;
} else {
REQUEST_HILOGE("File dir not include base dir: %{public}s, path dir: %{public}s",
baseDir.c_str(), filepath.c_str());
return false;
}
}
bool JsInitialize::Convert2FileSpec(ani_env *env, ani_object aniValue, const std::string &name, FileSpec &file)
{
REQUEST_HILOGI("Convert2FileSpec in");
file.name = name;
ani_ref pathRef;
if (ANI_OK != env->Object_GetPropertyByName_Ref(aniValue, "path", &pathRef)) {
REQUEST_HILOGE("Object_GetFieldByName_Ref value from data Faild");
return false;
}
file.uri = AniStringUtils::ToStd(env, static_cast<ani_string>(pathRef));
StringTrim(file.uri);
if (file.uri.empty()) {
return false;
}
file.filename = "";
ani_ref fileNameRef;
if (env->Object_GetPropertyByName_Ref(aniValue, "filename", &fileNameRef) == ANI_OK) {
file.filename = AniStringUtils::ToStd(env, static_cast<ani_string>(fileNameRef));
}
return true;
}
bool JsInitialize::Convert2FileSpecs(ani_env *env, ani_object aniValue, const std::string &name,
std::vector<FileSpec> &files)
{
UnionAccessor unionAccessor(env, aniValue);
std::vector<ani_ref> arrayValues = {};
if (!unionAccessor.TryConvertArray<ani_ref>(arrayValues) || arrayValues.empty()) {
return false;
}
bool ret = false;
for (uint16_t i = 0; i < arrayValues.size(); i++) {
ani_object data = static_cast<ani_object>(arrayValues[i]);
FileSpec file;
ret = Convert2FileSpec(env, data, name, file);
if (!ret) {
return false;
}
files.push_back(file);
}
return true;
}
}