From 904ab99852353430ec3fec3e51e30d0a33ad28aa Mon Sep 17 00:00:00 2001 From: Hollokin Date: Fri, 27 Oct 2023 09:20:43 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[=E6=96=B0=E9=9C=80=E6=B1=82]=E6=8B=B7?= =?UTF-8?q?=E8=B4=9D=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- bundle.json | 2 + file_api.gni | 1 + interfaces/kits/js/BUILD.gn | 6 + interfaces/kits/js/src/mod_fs/common_func.h | 9 + .../js/src/mod_fs/properties/copy_file.cpp | 252 ++++++++++++++++-- .../kits/js/src/mod_fs/properties/copy_file.h | 6 +- 6 files changed, 257 insertions(+), 19 deletions(-) diff --git a/bundle.json b/bundle.json index dbf370104..dd6270ec6 100644 --- a/bundle.json +++ b/bundle.json @@ -31,6 +31,8 @@ "common_event_service", "c_utils", "data_share", + "device_manager", + "dfs_service", "eventhandler", "hilog", "ipc", diff --git a/file_api.gni b/file_api.gni index d843a2cc7..65ca0707c 100644 --- a/file_api.gni +++ b/file_api.gni @@ -18,6 +18,7 @@ file_api_path = "//foundation/filemanagement/file_api" hiviewdfx_hilog_path = "//base/hiviewdfx/hilog" src_path = "${file_api_path}/interfaces/kits/js/src" utils_path = "${file_api_path}/utils" +filemanagement_service_path = "//foundation/filemanagement/dfs_service/services" use_mac = "${current_os}_${current_cpu}" == "mac_x64" || "${current_os}_${current_cpu}" == "mac_arm64" diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index d279adaeb..f91ae3ad0 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -109,6 +109,7 @@ ohos_shared_library("fs") { relative_install_dir = "module/file" include_dirs = [ + "${filemanagement_service_path}/distributedfiledaemon/include/ipc", "${src_path}/common", "${src_path}/common/file_helper", "${src_path}/mod_fs", @@ -182,8 +183,11 @@ ohos_shared_library("fs") { "src/mod_fs/properties/watcher.cpp", ] external_deps += [ + "ability_base:want", "ability_base:zuri", "ability_runtime:abilitykit_native", + "ability_runtime:uri_permission_mgr", + "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "app_file_service:fileuri_native", "bundle_framework:appexecfwk_base", @@ -191,6 +195,8 @@ ohos_shared_library("fs") { "c_utils:utils", "data_share:datashare_common", "data_share:datashare_consumer", + "device_manager:devicemanagersdk", + "dfs_service:distributed_file_daemon_kit_inner", "ipc:ipc_core", "samgr:samgr_proxy", ] diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index cc7293ddf..c231dee44 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -55,6 +55,15 @@ struct FileInfo { std::unique_ptr fdg = { nullptr }; }; +struct TotalFileInfo { + bool isPath = false; + bool isUri = false; + bool isRemoteUri = false; + std::unique_ptr path = { nullptr }; + std::string uri; + std::unique_ptr fdg = { nullptr }; +}; + void InitOpenMode(napi_env env, napi_value exports); void InitWhenceType(napi_env env, napi_value exports); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp index 71bb328b3..a3b116d12 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp @@ -23,21 +23,126 @@ #include #include +#include "accesstoken_kit.h" +#include "bundle_mgr_client_impl.h" #include "common_func.h" +#include "distributed_file_daemon_manager.h" #include "file_utils.h" #include "filemgmt_libhilog.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "uri.h" +#include "uri_permission_manager_client.h" +#include "want.h" namespace OHOS { namespace FileManagement { namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +using namespace OHOS::AppExecFwk; +const std::string FILE_PREFIX_NAME = "file://"; +const std::string NETWORK_PARA = "?networkid="; -static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) +// todo 待优化 +static bool CheckUri(const std::string &uri) { + HILOGI("tyx::CheckUri uri."); + return uri.find(FILE_PREFIX_NAME) == 0; +} + +static sptr GetBundleMgr() +{ + sptr systemAbilityManager = + OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + HILOGE("systemAbilityManager is nullptr"); + return nullptr; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (remoteObject == nullptr) { + HILOGE("remoteObject is nullptr"); + return nullptr; + } + return iface_cast(remoteObject); +} + +static std::string GetCurrentBundleName() +{ + HILOGI("tyx::GetCurrentBundleName in."); +// Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); +// auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); +// Security::AccessToken::HapTokenInfo info; +// auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, info); // 需要权限,用不了 + auto bundleMgr = GetBundleMgr(); + if (bundleMgr == nullptr) { + HILOGE("failed to get bunlde manager sa"); + return ""; + } + AppExecFwk::BundleInfo bundleInfo; + auto ret = bundleMgr->GetBundleInfoForSelf(0, bundleInfo); + HILOGI("tyx::GetCurrentBundleName GetBundleInfoForSelf end, ret = %{public}d.", ret); + HILOGI("tyx::GetCurrentBundleName GetBundleInfoForSelf end, bundleInfo.name = %{public}s.", bundleInfo.name.c_str()); + return bundleInfo.name; +} + +static bool IsValidUri(const std::string &uri) +{ + // 1、获取当前应用信息 + std::string currentBundleName = GetCurrentBundleName(); + // 2、检查是否为当前应用沙箱下的uri + std::string temp = uri.substr(FILE_PREFIX_NAME.size(), uri.size()); + return temp.find(currentBundleName) == 0; +} + +static bool IsRemoteUri(const std::string &uri) +{ + // NETWORK_PARA + return uri.find(NETWORK_PARA) != uri.npos; +} +// todo 优化 +static std::string ConvertUriToPath(const std::string &uri) +{ + HILOGI("tyx::ConvertUriToPath uri."); + if (!IsValidUri(uri)) { + return ""; + } + std::string currentBundleName = GetCurrentBundleName(); + HILOGI("tyx::GetCurrentBundleName end, bundleName = %{public}s.", currentBundleName.c_str()); + std::string temp = uri.substr(FILE_PREFIX_NAME.size(), uri.size()); + HILOGI("tyx::ConvertUriToPath, temp = %{public}s.", temp.c_str()); + return temp.substr(currentBundleName.size(), temp.size()); +} + +static std::string GetNetworkIdFromUri(const std::string &uri) +{ + HILOGI("tyx::GetNetworkIdFromUri uri."); + return uri.substr(uri.find(NETWORK_PARA) + NETWORK_PARA.size(), uri.size()); +} + +static NError IsAllPath(TotalFileInfo& srcFile, TotalFileInfo& destFile) +{ + std::string sPath; + std::string dPath; + if (srcFile.isUri) { + HILOGI("tyx::src is Uri."); + sPath = ConvertUriToPath(srcFile.uri); + } else { + HILOGI("tyx::src is not Uri."); + sPath = string(srcFile.path.get()); + } + if (destFile.isUri) { + HILOGI("tyx::dest is Uri."); + dPath = ConvertUriToPath(destFile.uri); + } else { + HILOGI("tyx::dest is not Uri."); + dPath = string(destFile.path.get()); + } #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) - filesystem::path srcPath(string(srcFile.path.get())); - filesystem::path dstPath(string(destFile.path.get())); + filesystem::path srcPath(sPath); + filesystem::path dstPath(dPath); error_code errCode; if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); @@ -50,7 +155,7 @@ static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) HILOGE("Failed to request heap memory."); return NError(ENOMEM); } - int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), srcFile.path.get(), destFile.path.get(), + int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), sPath.c_str(), dPath.c_str(), UV_FS_COPYFILE_FICLONE, nullptr); if (ret < 0) { HILOGE("Failed to copy file when all parameters are paths"); @@ -60,7 +165,49 @@ static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) return NError(ERRNO_NOERR); } -static NError SendFileCore(FileInfo& srcFdg, FileInfo& destFdg, struct stat& statbf) +static NError CopyFileFromSoftBus(TotalFileInfo& srcFile, TotalFileInfo& destFile) +{ + HILOGI("tyx::CopyFileFromSoftBus in."); +#if 0 + // todo 1、Uri鉴权-元能力 + auto &permissionClient = AAFwk::UriPermissionManagerClient::GetInstance(); + // bool VerifyUriPermission(const Uri &uri, uint32_t flag, uint32_t tokenId) + OHOS::Uri uri(srcFile.uri); + auto isVerified = permissionClient.VerifyUriPermission(uri, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, + IPCSkeleton::GetCallingTokenID()); + if (!isVerified) { + // todo uri权限校验失败,抛出错误码。 + return NError(-1); + } +#endif + if (destFile.isPath) { + // todo 2、建链-dfs_service-软总线 src和dest都校验好之后,才可以建链 + // todo uri和沙箱路径判断,判断都通过,建链 + auto packageName = GetCurrentBundleName(); + if (packageName.empty()) { + // todo 抛出错误码, + return NError(-1); + } + auto networkId = GetNetworkIdFromUri(srcFile.uri); // 复制端的设备id,粘贴端调用此接口 + HILOGI("tyx::CopyFileFromSoftBus, networkId = %{public}s.", networkId.c_str()); + // todo + // 如果destFile不是uri怎么办,这个uri必须是本地uri,不能是远端uri,如果是沙箱路径path行不行?应该也行。 + // todo 增加一个对destFile的判断比较。 + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( + srcFile.uri.c_str(), destFile.uri.c_str(), networkId); + HILOGI("tyx::PrepareSession, ret = %{public}d.", ret); + if (ret != 0) { + // todo 建联过程中的错误,抛出错误码 + return NError(-1); + } + return NError(ERRNO_NOERR); + } + // destFile不是个path,抛出错误。 + // todo destFile是不是必须是个目录才行? + return NError(-1); +} + +static NError SendFileCore(TotalFileInfo& srcFdg, TotalFileInfo& destFdg, struct stat& statbf) { std::unique_ptr sendfile_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -91,7 +238,7 @@ static NError SendFileCore(FileInfo& srcFdg, FileInfo& destFdg, struct stat& sta return NError(ERRNO_NOERR); } -static NError TruncateCore(const FileInfo& fileInfo) +static NError TruncateCore(const TotalFileInfo& fileInfo) { std::unique_ptr ftruncate_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -107,7 +254,7 @@ static NError TruncateCore(const FileInfo& fileInfo) return NError(ERRNO_NOERR); } -static NError OpenCore(FileInfo& fileInfo, const int flags, const int mode) +static NError OpenCore(TotalFileInfo& fileInfo, const int flags, const int mode) { std::unique_ptr open_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -128,8 +275,20 @@ static NError OpenCore(FileInfo& fileInfo, const int flags, const int mode) return NError(ERRNO_NOERR); } -static NError OpenFile(FileInfo& srcFile, FileInfo& destFile) +static NError OpenFile(TotalFileInfo& srcFile, TotalFileInfo& destFile) { + if (srcFile.isUri) { + std::string uri2Path = ConvertUriToPath(srcFile.uri); + srcFile.path = std::make_unique(uri2Path.length() + 1); + std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, srcFile.path.get()); + srcFile.isPath = true; + } + if (destFile.isUri) { + std::string uri2Path = ConvertUriToPath(srcFile.uri); + destFile.path = std::make_unique(uri2Path.length() + 1); + std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, destFile.path.get()); + destFile.isPath = true; + } if (srcFile.isPath) { auto openResult = OpenCore(srcFile, UV_FS_O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (openResult) { @@ -161,24 +320,67 @@ static NError OpenFile(FileInfo& srcFile, FileInfo& destFile) return SendFileCore(srcFile, destFile, statbf); } +static tuple GetModeFromOptionArg(napi_env env, napi_value argOption) +{ + NVal op(env, argOption); // 通用写法,将NVal中的val_置为待解析参数 + int32_t mode = 0; + bool succ = false; + + if (op.HasProp("mode") && !op.GetProp("mode").TypeIs(napi_undefined)) { // 待解析参数中是否有offset属性,如果能获取到,则进入if + tie(succ, mode) = op.GetProp("mode").ToInt32(); + if (!succ || mode != 0) { +// HILOGE("Illegal option.mode parameter"); + return { false, mode }; + } + } + + if (op.HasProp("progressListener") && !op.GetProp("progressListener").TypeIs(napi_undefined)) { // 解析progressListener参数 + // todo 保存进度监听回调 + } + + return { true, mode }; +} + static tuple ParseJsMode(napi_env env, const NFuncArg& funcArg) { bool succ = false; int mode = 0; + // todo 这个mode的值应该是多少?? if (funcArg.GetArgc() >= NARG_CNT::THREE) { + // 兼容mode和option tie(succ, mode) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(mode); if (!succ || mode) { - return { false, mode }; + // 在GetModeFromOptionArg中需要保存callback。 + tie(succ, mode) = GetModeFromOptionArg(env, funcArg[NARG_POS::SECOND]); + if (!succ || mode) { + return { false, mode }; + } } } return { true, mode }; } -static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg) +static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg) { + HILOGI("tyx::ParseJsOperand in."); auto [isPath, path, ignore] = pathOrFdFromJsArg.ToUTF8String(); if (isPath) { - return { true, FileInfo { true, move(path), {} } }; + HILOGI("tyx::isPath. path = %{public}s", path.get()); + if (!CheckUri(path.get())) { + HILOGI("tyx::not uri."); + return {true, TotalFileInfo{true, false, false, move(path), {}, {}}}; + } + if (!IsValidUri(path.get())) { // todo 抛出参数异常 + HILOGI("tyx::not vaild uri."); + return {false, TotalFileInfo{true, true, false, {}, {}, {}}}; + } + std::string uri2Path = ConvertUriToPath(path.get()); + std::unique_ptr tempPath = std::make_unique(uri2Path.length() + 1); + std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, tempPath.get()); + if (IsRemoteUri(path.get())) { + return {true, TotalFileInfo{true, true, true, move(tempPath), path.get(), {}}}; + } + return {true, TotalFileInfo{true, false, false, move(tempPath), {}, {}}}; } auto [isFd, fd] = pathOrFdFromJsArg.ToInt32(); @@ -187,13 +389,13 @@ static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg if (fdg == nullptr) { HILOGE("Failed to request heap memory."); NError(ENOMEM).ThrowErr(env); - return { false, FileInfo { false, {}, {} } }; + return {false, TotalFileInfo{false, false, false, {}, {}, {}}}; } - return { true, FileInfo { false, {}, move(fdg) } }; + return { true, TotalFileInfo { false, false, false, {}, {}, move(fdg) } }; } - return { false, FileInfo { false, {}, {} } }; -}; + return { false, TotalFileInfo { false, {}, {} } }; +} napi_value CopyFile::Sync(napi_env env, napi_callback_info info) { @@ -237,6 +439,7 @@ napi_value CopyFile::Sync(napi_env env, napi_callback_info info) napi_value CopyFile::Async(napi_env env, napi_callback_info info) { + HILOGI("tyx::CopyFile::Async in."); NFuncArg funcArg(env, info); if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { HILOGE("Number of arguments unmatched"); @@ -245,7 +448,9 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) } auto [succSrc, src] = ParseJsOperand(env, { env, funcArg[NARG_POS::FIRST] }); + HILOGI("tyx::CopyFile::Async ParseJsOperand src end."); auto [succDest, dest] = ParseJsOperand(env, { env, funcArg[NARG_POS::SECOND] }); + HILOGI("tyx::CopyFile::Async ParseJsOperand dest end."); if (!succSrc || !succDest) { HILOGE("The first/second argument requires filepath/fd"); NError(EINVAL).ThrowErr(env); @@ -253,6 +458,7 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) } auto [succMode, mode] = ParseJsMode(env, funcArg); + HILOGI("tyx::CopyFile::Async ParseJsOperand mode end."); if (!succMode) { HILOGE("Failed to convert mode to int32"); NError(EINVAL).ThrowErr(env); @@ -265,8 +471,22 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } + if (para->dest_.isRemoteUri) { + HILOGE("dest cannot be remote uri."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + if (para->src_.isRemoteUri && (!para->dest_.isPath && !para->dest_.isUri)) { + HILOGE("dest not path or uri."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } auto cbExec = [para]() -> NError { - if (para->src_.isPath && para->dest_.isPath) { + if (para->src_.isRemoteUri && para->dest_.isPath) { + // todo 走新流程 需要适配同步接口不? + return CopyFileFromSoftBus(para->src_, para->dest_); + } + if ((para->src_.isPath || para->src_.isUri) && (para->dest_.isPath || para->dest_.isUri)) { return IsAllPath(para->src_, para->dest_); } return OpenFile(para->src_, para->dest_); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.h b/interfaces/kits/js/src/mod_fs/properties/copy_file.h index 2801c4a43..18d1558f8 100755 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.h @@ -31,10 +31,10 @@ public: class Para { public: - FileInfo src_; - FileInfo dest_; + TotalFileInfo src_; + TotalFileInfo dest_; - Para(FileInfo src, FileInfo dest) : src_(move(src)), dest_(move(dest)){}; + Para(TotalFileInfo src, TotalFileInfo dest) : src_(move(src)), dest_(move(dest)){}; }; constexpr size_t MAX_SIZE = 0x7ffff000; const string PROCEDURE_COPYFILE_NAME = "FileIOCopyFile"; -- Gitee From 5a6d3fe7ce35f306d41496ae3820f28214aa8a39 Mon Sep 17 00:00:00 2001 From: Hollokin Date: Tue, 31 Oct 2023 15:54:23 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8B=B7=E8=B4=9D=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hollokin --- interfaces/kits/js/src/mod_fs/common_func.h | 9 - .../js/src/mod_fs/properties/copy_file.cpp | 240 ++++++++---------- .../kits/js/src/mod_fs/properties/copy_file.h | 6 +- 3 files changed, 105 insertions(+), 150 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index c231dee44..cc7293ddf 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -55,15 +55,6 @@ struct FileInfo { std::unique_ptr fdg = { nullptr }; }; -struct TotalFileInfo { - bool isPath = false; - bool isUri = false; - bool isRemoteUri = false; - std::unique_ptr path = { nullptr }; - std::string uri; - std::unique_ptr fdg = { nullptr }; -}; - void InitOpenMode(napi_env env, napi_value exports); void InitWhenceType(napi_env env, napi_value exports); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp index a3b116d12..85e59e864 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp @@ -46,13 +46,6 @@ using namespace OHOS::AppExecFwk; const std::string FILE_PREFIX_NAME = "file://"; const std::string NETWORK_PARA = "?networkid="; -// todo 待优化 -static bool CheckUri(const std::string &uri) -{ - HILOGI("tyx::CheckUri uri."); - return uri.find(FILE_PREFIX_NAME) == 0; -} - static sptr GetBundleMgr() { sptr systemAbilityManager = @@ -72,10 +65,6 @@ static sptr GetBundleMgr() static std::string GetCurrentBundleName() { HILOGI("tyx::GetCurrentBundleName in."); -// Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); -// auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); -// Security::AccessToken::HapTokenInfo info; -// auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, info); // 需要权限,用不了 auto bundleMgr = GetBundleMgr(); if (bundleMgr == nullptr) { HILOGE("failed to get bunlde manager sa"); @@ -90,6 +79,10 @@ static std::string GetCurrentBundleName() static bool IsValidUri(const std::string &uri) { + HILOGI("tyx::IsValidUri uri."); + if (uri.find(FILE_PREFIX_NAME) != 0) { + return false; + } // 1、获取当前应用信息 std::string currentBundleName = GetCurrentBundleName(); // 2、检查是否为当前应用沙箱下的uri @@ -102,19 +95,6 @@ static bool IsRemoteUri(const std::string &uri) // NETWORK_PARA return uri.find(NETWORK_PARA) != uri.npos; } -// todo 优化 -static std::string ConvertUriToPath(const std::string &uri) -{ - HILOGI("tyx::ConvertUriToPath uri."); - if (!IsValidUri(uri)) { - return ""; - } - std::string currentBundleName = GetCurrentBundleName(); - HILOGI("tyx::GetCurrentBundleName end, bundleName = %{public}s.", currentBundleName.c_str()); - std::string temp = uri.substr(FILE_PREFIX_NAME.size(), uri.size()); - HILOGI("tyx::ConvertUriToPath, temp = %{public}s.", temp.c_str()); - return temp.substr(currentBundleName.size(), temp.size()); -} static std::string GetNetworkIdFromUri(const std::string &uri) { @@ -122,27 +102,11 @@ static std::string GetNetworkIdFromUri(const std::string &uri) return uri.substr(uri.find(NETWORK_PARA) + NETWORK_PARA.size(), uri.size()); } -static NError IsAllPath(TotalFileInfo& srcFile, TotalFileInfo& destFile) +static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) { - std::string sPath; - std::string dPath; - if (srcFile.isUri) { - HILOGI("tyx::src is Uri."); - sPath = ConvertUriToPath(srcFile.uri); - } else { - HILOGI("tyx::src is not Uri."); - sPath = string(srcFile.path.get()); - } - if (destFile.isUri) { - HILOGI("tyx::dest is Uri."); - dPath = ConvertUriToPath(destFile.uri); - } else { - HILOGI("tyx::dest is not Uri."); - dPath = string(destFile.path.get()); - } #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) - filesystem::path srcPath(sPath); - filesystem::path dstPath(dPath); + filesystem::path srcPath(string(srcFile.path.get())); + filesystem::path dstPath(string(destFile.path.get())); error_code errCode; if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); @@ -155,7 +119,7 @@ static NError IsAllPath(TotalFileInfo& srcFile, TotalFileInfo& destFile) HILOGE("Failed to request heap memory."); return NError(ENOMEM); } - int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), sPath.c_str(), dPath.c_str(), + int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), srcFile.path.get(), destFile.path.get(), UV_FS_COPYFILE_FICLONE, nullptr); if (ret < 0) { HILOGE("Failed to copy file when all parameters are paths"); @@ -165,7 +129,7 @@ static NError IsAllPath(TotalFileInfo& srcFile, TotalFileInfo& destFile) return NError(ERRNO_NOERR); } -static NError CopyFileFromSoftBus(TotalFileInfo& srcFile, TotalFileInfo& destFile) +static NError CopyFileFromSoftBus(const char *remoteUri, const char *destPath) { HILOGI("tyx::CopyFileFromSoftBus in."); #if 0 @@ -180,34 +144,26 @@ static NError CopyFileFromSoftBus(TotalFileInfo& srcFile, TotalFileInfo& destFil return NError(-1); } #endif - if (destFile.isPath) { - // todo 2、建链-dfs_service-软总线 src和dest都校验好之后,才可以建链 - // todo uri和沙箱路径判断,判断都通过,建链 - auto packageName = GetCurrentBundleName(); - if (packageName.empty()) { - // todo 抛出错误码, - return NError(-1); - } - auto networkId = GetNetworkIdFromUri(srcFile.uri); // 复制端的设备id,粘贴端调用此接口 - HILOGI("tyx::CopyFileFromSoftBus, networkId = %{public}s.", networkId.c_str()); - // todo - // 如果destFile不是uri怎么办,这个uri必须是本地uri,不能是远端uri,如果是沙箱路径path行不行?应该也行。 - // todo 增加一个对destFile的判断比较。 - auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( - srcFile.uri.c_str(), destFile.uri.c_str(), networkId); - HILOGI("tyx::PrepareSession, ret = %{public}d.", ret); - if (ret != 0) { - // todo 建联过程中的错误,抛出错误码 - return NError(-1); - } - return NError(ERRNO_NOERR); + // todo 2、建链-dfs_service-软总线 + auto packageName = GetCurrentBundleName(); + if (packageName.empty()) { + // todo 抛出错误码, + return NError(-1); + } + + auto networkId = GetNetworkIdFromUri(remoteUri); // 复制端的设备id,粘贴端调用此接口 + HILOGI("tyx::CopyFileFromSoftBus, networkId = %{public}s.", networkId.c_str()); + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( + remoteUri, destPath, networkId); + HILOGI("tyx::PrepareSession, ret = %{public}d.", ret); + if (ret != 0) { + // todo 建联过程中的错误,抛出错误码 + return NError(-1); } - // destFile不是个path,抛出错误。 - // todo destFile是不是必须是个目录才行? - return NError(-1); + return NError(ERRNO_NOERR); } -static NError SendFileCore(TotalFileInfo& srcFdg, TotalFileInfo& destFdg, struct stat& statbf) +static NError SendFileCore(FileInfo& srcFdg, FileInfo& destFdg, struct stat& statbf) { std::unique_ptr sendfile_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -238,7 +194,7 @@ static NError SendFileCore(TotalFileInfo& srcFdg, TotalFileInfo& destFdg, struct return NError(ERRNO_NOERR); } -static NError TruncateCore(const TotalFileInfo& fileInfo) +static NError TruncateCore(const FileInfo& fileInfo) { std::unique_ptr ftruncate_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -254,7 +210,7 @@ static NError TruncateCore(const TotalFileInfo& fileInfo) return NError(ERRNO_NOERR); } -static NError OpenCore(TotalFileInfo& fileInfo, const int flags, const int mode) +static NError OpenCore(FileInfo& fileInfo, const int flags, const int mode) { std::unique_ptr open_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -275,20 +231,8 @@ static NError OpenCore(TotalFileInfo& fileInfo, const int flags, const int mode) return NError(ERRNO_NOERR); } -static NError OpenFile(TotalFileInfo& srcFile, TotalFileInfo& destFile) +static NError OpenFile(FileInfo& srcFile, FileInfo& destFile) { - if (srcFile.isUri) { - std::string uri2Path = ConvertUriToPath(srcFile.uri); - srcFile.path = std::make_unique(uri2Path.length() + 1); - std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, srcFile.path.get()); - srcFile.isPath = true; - } - if (destFile.isUri) { - std::string uri2Path = ConvertUriToPath(srcFile.uri); - destFile.path = std::make_unique(uri2Path.length() + 1); - std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, destFile.path.get()); - destFile.isPath = true; - } if (srcFile.isPath) { auto openResult = OpenCore(srcFile, UV_FS_O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (openResult) { @@ -320,67 +264,87 @@ static NError OpenFile(TotalFileInfo& srcFile, TotalFileInfo& destFile) return SendFileCore(srcFile, destFile, statbf); } -static tuple GetModeFromOptionArg(napi_env env, napi_value argOption) +static tuple GetModeFromOptionArg(napi_env env, const NFuncArg& funcArg) { - NVal op(env, argOption); // 通用写法,将NVal中的val_置为待解析参数 int32_t mode = 0; bool succ = false; + if (funcArg.GetArgc() >= NARG_CNT::THREE) { + NVal op(env, funcArg[NARG_POS::THIRD]); - if (op.HasProp("mode") && !op.GetProp("mode").TypeIs(napi_undefined)) { // 待解析参数中是否有offset属性,如果能获取到,则进入if - tie(succ, mode) = op.GetProp("mode").ToInt32(); - if (!succ || mode != 0) { -// HILOGE("Illegal option.mode parameter"); - return { false, mode }; + if (op.HasProp("mode") && !op.GetProp("mode").TypeIs(napi_undefined)) { + tie(succ, mode) = op.GetProp("mode").ToInt32(); + if (!succ || mode != 0) { + HILOGE("Illegal options.mode parameter"); + return { false, mode, NVal() }; + } } - } - if (op.HasProp("progressListener") && !op.GetProp("progressListener").TypeIs(napi_undefined)) { // 解析progressListener参数 - // todo 保存进度监听回调 + if (op.HasProp("progressListener") && !op.GetProp("progressListener").TypeIs(napi_undefined)) { + if (!op.GetProp("progressListener").TypeIs(napi_function)) { + HILOGE("Illegal options.progressListener type"); + return { false, mode, NVal() }; + } + return { true, mode, op.GetProp("progressListener") }; + } } - - return { true, mode }; + return { true, mode, NVal() }; } static tuple ParseJsMode(napi_env env, const NFuncArg& funcArg) { bool succ = false; int mode = 0; - // todo 这个mode的值应该是多少?? if (funcArg.GetArgc() >= NARG_CNT::THREE) { - // 兼容mode和option tie(succ, mode) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(mode); if (!succ || mode) { - // 在GetModeFromOptionArg中需要保存callback。 - tie(succ, mode) = GetModeFromOptionArg(env, funcArg[NARG_POS::SECOND]); - if (!succ || mode) { - return { false, mode }; - } + return { false, mode }; } } return { true, mode }; } -static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg) +static bool IsDirectory(char* path) +{ + struct stat buf; + int ret = stat(path, &buf); + if (ret == -1) { + HILOGI("tyx::stat failed, errno is %{public}d, ", errno); + return false; + } + return (buf.st_mode & S_IFMT) == S_IFDIR; +} + +static bool IsFile(char* path) +{ + struct stat buf; + int ret = stat(path, &buf); + if (ret == -1) { + HILOGI("tyx::stat failed, errno is %{public}d, ", errno); + return false; + } + return (buf.st_mode & S_IFMT) == S_IFREG; +} + +static bool CheckValidParam(FileInfo &src, FileInfo &dest) +{ + if (src.isPath && dest.isPath) { + return IsValidUri(src.path.get()) ? IsRemoteUri(src.path.get()) && IsDirectory(dest.path.get()) + : IsFile(src.path.get()) && IsFile(dest.path.get()); + } + + if (src.isPath) { + return IsFile(src.path.get()); + } + return dest.isPath ? IsFile(dest.path.get()) : true; +} + +static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg) { HILOGI("tyx::ParseJsOperand in."); auto [isPath, path, ignore] = pathOrFdFromJsArg.ToUTF8String(); if (isPath) { HILOGI("tyx::isPath. path = %{public}s", path.get()); - if (!CheckUri(path.get())) { - HILOGI("tyx::not uri."); - return {true, TotalFileInfo{true, false, false, move(path), {}, {}}}; - } - if (!IsValidUri(path.get())) { // todo 抛出参数异常 - HILOGI("tyx::not vaild uri."); - return {false, TotalFileInfo{true, true, false, {}, {}, {}}}; - } - std::string uri2Path = ConvertUriToPath(path.get()); - std::unique_ptr tempPath = std::make_unique(uri2Path.length() + 1); - std::copy_n(uri2Path.c_str(), uri2Path.length() + 1, tempPath.get()); - if (IsRemoteUri(path.get())) { - return {true, TotalFileInfo{true, true, true, move(tempPath), path.get(), {}}}; - } - return {true, TotalFileInfo{true, false, false, move(tempPath), {}, {}}}; + return { true, FileInfo { true, move(path), {} } }; } auto [isFd, fd] = pathOrFdFromJsArg.ToInt32(); @@ -389,12 +353,11 @@ static tuple ParseJsOperand(napi_env env, NVal pathOrFdFrom if (fdg == nullptr) { HILOGE("Failed to request heap memory."); NError(ENOMEM).ThrowErr(env); - return {false, TotalFileInfo{false, false, false, {}, {}, {}}}; + return { false, FileInfo { false, {}, {} } }; } - return { true, TotalFileInfo { false, false, false, {}, {}, move(fdg) } }; + return { true, FileInfo { false, {}, move(fdg) } }; } - - return { false, TotalFileInfo { false, {}, {} } }; + return { false, FileInfo { false, {}, {} } }; } napi_value CopyFile::Sync(napi_env env, napi_callback_info info) @@ -461,6 +424,18 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) HILOGI("tyx::CopyFile::Async ParseJsOperand mode end."); if (!succMode) { HILOGE("Failed to convert mode to int32"); + auto [succOptions, mode, listener] = GetModeFromOptionArg(env, funcArg); + if (!succOptions) { + HILOGE("Failed to convert options"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + // 注册listener + } + + bool validParam = CheckValidParam(src, dest); + if (!validParam) { + HILOGE("tyx::Param is not valid."); NError(EINVAL).ThrowErr(env); return nullptr; } @@ -471,22 +446,11 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } - if (para->dest_.isRemoteUri) { - HILOGE("dest cannot be remote uri."); - NError(EINVAL).ThrowErr(env); - return nullptr; - } - if (para->src_.isRemoteUri && (!para->dest_.isPath && !para->dest_.isUri)) { - HILOGE("dest not path or uri."); - NError(EINVAL).ThrowErr(env); - return nullptr; - } auto cbExec = [para]() -> NError { - if (para->src_.isRemoteUri && para->dest_.isPath) { - // todo 走新流程 需要适配同步接口不? - return CopyFileFromSoftBus(para->src_, para->dest_); + if (IsRemoteUri(para->src_.path.get()) && IsDirectory(para->dest_.path.get())) { + return CopyFileFromSoftBus(para->src_.path.get(), para->dest_.path.get()); } - if ((para->src_.isPath || para->src_.isUri) && (para->dest_.isPath || para->dest_.isUri)) { + if (para->src_.isPath && para->dest_.isPath) { return IsAllPath(para->src_, para->dest_); } return OpenFile(para->src_, para->dest_); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.h b/interfaces/kits/js/src/mod_fs/properties/copy_file.h index 18d1558f8..2801c4a43 100755 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.h @@ -31,10 +31,10 @@ public: class Para { public: - TotalFileInfo src_; - TotalFileInfo dest_; + FileInfo src_; + FileInfo dest_; - Para(TotalFileInfo src, TotalFileInfo dest) : src_(move(src)), dest_(move(dest)){}; + Para(FileInfo src, FileInfo dest) : src_(move(src)), dest_(move(dest)){}; }; constexpr size_t MAX_SIZE = 0x7ffff000; const string PROCEDURE_COPYFILE_NAME = "FileIOCopyFile"; -- Gitee