From f5bf195773b188958d0b1cb75e6cba87f5e1fa84 Mon Sep 17 00:00:00 2001 From: lvyuanyuan Date: Mon, 4 Mar 2024 10:58:32 +0800 Subject: [PATCH] =?UTF-8?q?fs.copy=E6=94=AF=E6=8C=81=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lvyuanyuan Change-Id: I7e12fd4fe84a061bde1c0551bae9b785e328b534 --- interfaces/kits/js/BUILD.gn | 4 + interfaces/kits/js/src/common/napi/n_class.h | 4 +- .../class_tasksignal/task_signal_entity.cpp | 76 +++++++++ .../class_tasksignal/task_signal_entity.h | 46 ++++++ .../task_signal_n_exporter.cpp | 133 ++++++++++++++++ .../class_tasksignal/task_signal_n_exporter.h | 41 +++++ interfaces/kits/js/src/mod_fs/module.cpp | 2 + .../kits/js/src/mod_fs/properties/copy.cpp | 149 ++++++++++++------ .../kits/js/src/mod_fs/properties/copy.h | 12 +- .../copy_listener/trans_listener.cpp | 11 +- .../properties/copy_listener/trans_listener.h | 1 + interfaces/kits/native/BUILD.gn | 47 ++++++ .../kits/native/task_signal/task_signal.cpp | 89 +++++++++++ .../kits/native/task_signal/task_signal.h | 48 ++++++ .../native/task_signal/task_signal_listener.h | 30 ++++ interfaces/test/unittest/BUILD.gn | 1 + interfaces/test/unittest/task_signal/BUILD.gn | 42 +++++ .../unittest/task_signal/task_signal_test.cpp | 138 ++++++++++++++++ utils/filemgmt_libn/include/n_class.h | 4 +- utils/filemgmt_libn/include/n_error.h | 12 +- 20 files changed, 830 insertions(+), 60 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h create mode 100644 interfaces/kits/native/task_signal/task_signal.cpp create mode 100644 interfaces/kits/native/task_signal/task_signal.h create mode 100644 interfaces/kits/native/task_signal/task_signal_listener.h create mode 100644 interfaces/test/unittest/task_signal/BUILD.gn create mode 100644 interfaces/test/unittest/task_signal/task_signal_test.cpp diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 20648a0b7..60291831a 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -117,6 +117,7 @@ ohos_shared_library("fs") { include_dirs = [ "${filemanagement_service_path}/distributedfiledaemon/include/ipc", + "${filemanagement_service_path}/distributedfiledaemon/include/common", "${src_path}/common", "${src_path}/common/file_helper", "${src_path}/mod_fs", @@ -151,6 +152,7 @@ ohos_shared_library("fs") { deps = [ "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libn:filemgmt_libn", + "${file_api_path}/interfaces/kits/native:task_signal_native", ] use_exceptions = true @@ -184,6 +186,8 @@ ohos_shared_library("fs") { "src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp", "src/mod_fs/class_stream/flush.cpp", "src/mod_fs/class_stream/stream_n_exporter.cpp", + "src/mod_fs/class_tasksignal/task_signal_entity.cpp", + "src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp", "src/mod_fs/class_watcher/watcher_entity.cpp", "src/mod_fs/class_watcher/watcher_n_exporter.cpp", "src/mod_fs/properties/copy.cpp", diff --git a/interfaces/kits/js/src/common/napi/n_class.h b/interfaces/kits/js/src/common/napi/n_class.h index 171b7f627..831210b2b 100644 --- a/interfaces/kits/js/src/common/napi/n_class.h +++ b/interfaces/kits/js/src/common/napi/n_class.h @@ -40,13 +40,13 @@ public: template static T *GetEntityOf(napi_env env, napi_value objStat) { if (!env || !objStat) { - HILOGE("Empty input: env %d, obj %d", env == nullptr, objStat == nullptr); + HILOGE("Empty input: env %{public}d, obj %{public}d", env == nullptr, objStat == nullptr); return nullptr; } T *t = nullptr; napi_status status = napi_unwrap(env, objStat, (void **)&t); if (status != napi_ok) { - HILOGE("Cannot umwarp for pointer: %d", status); + HILOGE("Cannot umwarp for pointer: %{public}d", status); return nullptr; } return t; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp new file mode 100644 index 000000000..aeb23baf0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 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 "task_signal_entity.h" + +#include +namespace OHOS::FileManagement::ModuleFileIO { +TaskSignalEntity::~TaskSignalEntity() {} + +void TaskSignalEntity::OnCancel(const std::string &path) +{ + HILOGI("OnCancel run in. path = %{public}s", path.c_str()); + uv_loop_s *loop = nullptr; + if (!callbackContext) { + HILOGE("Failed to get callback context."); + return; + } + auto env = callbackContext->env_; + callbackContext->filePath = path; + napi_get_uv_event_loop(env, &loop); + if (loop == nullptr) { + HILOGE("Failed to get uv event loop"); + return; + } + uv_work_t *work = new (std::nothrow) uv_work_t; + if (work == nullptr) { + HILOGE("Failed to create uv_work_t pointer"); + return; + } + work->data = reinterpret_cast(callbackContext.get()); + uv_queue_work_with_qos( + loop, work, [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + JSCallbackContext *callbackContext = reinterpret_cast(work->data); + if (callbackContext == nullptr) { + HILOGE("Failed to create context pointer"); + return; + } + if (!callbackContext->ref_) { + HILOGE("Failed to get nref reference"); + return; + } + napi_handle_scope scope = nullptr; + napi_status ret = napi_open_handle_scope(callbackContext->env_, &scope); + if (ret != napi_ok) { + HILOGE("Failed to open handle scope, ret: %{public}d", ret); + return; + } + napi_env env = callbackContext->env_; + napi_value jsCallback = callbackContext->ref_.Deref(env).val_; + napi_value filePath = LibN::NVal::CreateUTF8String(env, callbackContext->filePath).val_; + napi_value retVal = nullptr; + ret = napi_call_function(env, nullptr, jsCallback, 1, &filePath, &retVal); + if (ret != napi_ok) { + HILOGE("Failed to call napi_call_function, ret: %{public}d", ret); + } + ret = napi_close_handle_scope(callbackContext->env_, scope); + if (ret != napi_ok) { + HILOGE("Failed to close handle scope, ret: %{public}d", ret); + } + }, + uv_qos_user_initiated); +} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h new file mode 100644 index 000000000..6ceda7548 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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 FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H + +#include "filemgmt_libn.h" +#include "task_signal.h" +#include "task_signal_listener.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace DistributedFS::ModuleTaskSignal; +class JSCallbackContext { +public: + explicit JSCallbackContext(LibN::NVal jsVal) : ref_(jsVal) {} + ~JSCallbackContext() = default; + + napi_env env_; + LibN::NRef ref_; + std::string filePath; +}; + +class TaskSignalEntity : public TaskSignalListener { +public: + TaskSignalEntity() = default; + ~TaskSignalEntity() override; + void OnCancel(const std::string &path) override; + + std::shared_ptr taskSignal = nullptr; + std::shared_ptr callbackContext = nullptr; +}; +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_H diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp new file mode 100644 index 000000000..1feb1bcff --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2024 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 "task_signal_n_exporter.h" + +#include "file_utils.h" +#include "task_signal.h" +#include "task_signal_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; +using namespace DistributedFS::ModuleTaskSignal; +constexpr int NO_ERROR = 0; +constexpr int CANCEL_ERR = -3; +TaskSignalNExporter::TaskSignalNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +TaskSignalNExporter::~TaskSignalNExporter() {} + +string TaskSignalNExporter::GetClassName() +{ + return TaskSignalNExporter::className_; +} + +napi_value TaskSignalNExporter::Constructor(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Failed to get param."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto taskSignalEntity = CreateUniquePtr(); + if (taskSignalEntity == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + taskSignalEntity->taskSignal = std::make_shared(); + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), std::move(taskSignalEntity))) { + HILOGE("Failed to set watcherEntity."); + NError(EIO).ThrowErr(env); + return nullptr; + } + return funcArg.GetThisVar(); +} + +bool TaskSignalNExporter::Export() +{ + vector props = { + NVal::DeclareNapiFunction("cancel", Cancel), + NVal::DeclareNapiFunction("onCancel", OnCancel), + }; + string className = GetClassName(); + + auto [succ, classValue] = NClass::DefineClass(exports_.env_, className_, Constructor, std::move(props)); + if (!succ) { + HILOGE("Failed to DefineClass"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Failed to SaveClass"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + return exports_.AddProp(className, classValue); +} + +napi_value TaskSignalNExporter::Cancel(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Failed to get param when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!taskSignalEntity) { + HILOGE("Failed to get watcherEntity when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto ret = taskSignalEntity->taskSignal->Cancel(); + if (ret != NO_ERROR) { + HILOGE("Failed to cancel the task."); + NError(CANCEL_ERR).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value TaskSignalNExporter::OnCancel(napi_env env, napi_callback_info info) +{ + HILOGI("Run in."); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Failed to get param when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto taskSignalEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!taskSignalEntity) { + HILOGE("Failed to get watcherEntity when stop."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + std::shared_ptr signal(taskSignalEntity); + taskSignalEntity->taskSignal->SetTaskSignalListener(signal); + auto callbackContext = std::make_shared(NVal(env, funcArg[0])); + callbackContext->env_ = env; + taskSignalEntity->callbackContext = callbackContext; + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h new file mode 100644 index 000000000..b3bc50e0e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_n_exporter.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 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 FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H + +#include + +#include "filemgmt_libn.h" +#include "task_signal_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class TaskSignalNExporter final : public LibN::NExporter { +public: + inline static const std::string className_ = "TaskSignal"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info info); + static napi_value Cancel(napi_env env, napi_callback_info info); + static napi_value OnCancel(napi_env env, napi_callback_info info); + + TaskSignalNExporter(napi_env env, napi_value exports); + ~TaskSignalNExporter() override; +}; +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_N_EXPORTER_H diff --git a/interfaces/kits/js/src/mod_fs/module.cpp b/interfaces/kits/js/src/mod_fs/module.cpp index 70086e994..65ba67efd 100644 --- a/interfaces/kits/js/src/mod_fs/module.cpp +++ b/interfaces/kits/js/src/mod_fs/module.cpp @@ -24,6 +24,7 @@ #include "class_randomaccessfile/randomaccessfile_n_exporter.h" #include "class_readeriterator/readeriterator_n_exporter.h" #include "class_stream/stream_n_exporter.h" +#include "class_tasksignal/task_signal_n_exporter.h" #include "class_watcher/watcher_n_exporter.h" #endif #include "filemgmt_libhilog.h" @@ -47,6 +48,7 @@ static napi_value Export(napi_env env, napi_value exports) products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); #endif for (auto &&product : products) { #ifdef WIN_PLATFORM diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 1aa3c7465..a5db4d81d 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -24,12 +24,15 @@ #include #include #include +#include #include #include #include #include #include +#include "../../common/file_helper/fd_guard.h" +#include "../class_tasksignal/task_signal_n_exporter.h" #include "file_uri.h" #include "file_utils.h" #include "filemgmt_libhilog.h" @@ -49,7 +52,7 @@ const string PROCEDURE_COPY_NAME = "FileFSCopy"; constexpr int DISMATCH = 0; constexpr int MATCH = 1; constexpr int BUF_SIZE = 1024; -constexpr size_t MAX_SIZE = 0x7ffff000; +constexpr int64_t COPY_CHECKPOINT_BYTES = 524288; constexpr std::chrono::milliseconds NOTIFY_PROGRESS_DELAY(200); std::recursive_mutex Copy::mutex_; std::map> Copy::jsCbMap_; @@ -88,6 +91,21 @@ tuple Copy::GetListenerFromOptionArg(napi_env env, const NFuncArg &f return { true, NVal() }; } +tuple Copy::GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg) +{ + if (funcArg.GetArgc() >= NARG_CNT::THREE) { + NVal op(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("copySignal") && !op.GetProp("copySignal").TypeIs(napi_undefined)) { + if (!op.GetProp("copySignal").TypeIs(napi_object)) { + HILOGE("Illegal options.progressListener type"); + return { false, NVal() }; + } + return { true, op.GetProp("copySignal") }; + } + } + return { true, NVal() }; +} + bool Copy::IsRemoteUri(const std::string &uri) { // NETWORK_PARA @@ -139,49 +157,58 @@ void Copy::CheckOrCreatePath(const std::string &destPath) } } -int Copy::CopyFile(const string &src, const string &dest) +int Copy::SendFile(const string &src, const string &dest, std::shared_ptr infos) { HILOGD("src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); - auto srcFd = open(src.c_str(), O_RDONLY); - auto destFd = open(dest.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (srcFd < 0 || destFd < 0) { - HILOGE("Error opening file descriptor. errno = %{public}d", errno); - close(srcFd); - close(destFd); - return errno; - } - auto srcFdg = CreateUniquePtr(srcFd, true); - auto destFdg = CreateUniquePtr(destFd, true); - std::unique_ptr sendFileReq = { - new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (sendFileReq == nullptr) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - int64_t offset = 0; - struct stat srcStat{}; - if (fstat(srcFdg->GetFD(), &srcStat) < 0) { - HILOGE("Failed to get stat of file by fd: %{public}d ,errno = %{public}d", srcFdg->GetFD(), errno); - return errno; - } - int64_t size = static_cast(srcStat.st_size); - int ret = 0; - while (size > 0) { - ret = uv_fs_sendfile(nullptr, sendFileReq.get(), destFdg->GetFD(), srcFdg->GetFD(), - offset, MAX_SIZE, nullptr); - if (ret < 0) { - HILOGE("Failed to sendfile by errno : %{public}d", errno); - return errno; + DistributedFS::FDGuard sfd; + DistributedFS::FDGuard ofd; + struct stat attrSrc; + if (stat(src.c_str(), &attrSrc) == FAILED) { + HILOGE("Stat failed, src = %{public}s, errno = %{public}d", src.c_str(), errno); + return EIO; + } + sfd.SetFD(open(src.c_str(), O_RDONLY)); + ofd.SetFD(open(dest.c_str(), O_WRONLY | O_CREAT, attrSrc.st_mode)); + if (sfd.GetFD() == FAILED || ofd.GetFD() == FAILED) { + return EIO; + } + int ret = EIO; + auto fileSize = attrSrc.st_size; + if (fileSize <= COPY_CHECKPOINT_BYTES) { + if (sendfile(ofd.GetFD(), sfd.GetFD(), nullptr, fileSize) == -1) { + HILOGE("Sendfile failed, errno = %{public}d", errno); + remove(dest.c_str()); + return EIO; } - offset += static_cast(ret); - size -= static_cast(ret); - if (ret == 0) { - break; + if (infos != nullptr && infos->taskSignal != nullptr) { + if (infos->taskSignal->CheckCancelIfNeed(src)) { + HILOGE("Operation canceled."); + return ECANCELED; + } + } + } else { + HILOGI("Start to sendfile.infos != nullptr: %{public}d, infos->taskSignal != nullptr: %{public}d", + infos != nullptr, infos->taskSignal != nullptr); + off_t offset = 0; + while ((ret = sendfile(ofd.GetFD(), sfd.GetFD(), &offset, COPY_CHECKPOINT_BYTES)) != -1) { + if (infos != nullptr && infos->taskSignal != nullptr) { + if (infos->taskSignal->CheckCancelIfNeed(src)) { + HILOGE("Operation canceled."); + return ECANCELED; + } + } + if (ret == 0) { + if (offset < fileSize) { + return EIO; + } + return ERRNO_NOERR; + } + offset += ret; + } + if (ret == -1) { + remove(dest.c_str()); + return EIO; } - } - if (size != 0) { - HILOGE("The execution of the sendfile task was terminated, remaining file size %{public}" PRIu64, size); - return E_IO; } return ERRNO_NOERR; } @@ -321,7 +348,7 @@ int Copy::RecurCopyDir(const string &srcPath, const string &destPath, std::share ret = CopySubDir(src, dest, infos); } else { infos->filePaths.insert(dest); - ret = CopyFile(src, dest); + ret = SendFile(src, dest); } if (ret != ERRNO_NOERR) { return ret; @@ -356,6 +383,7 @@ int Copy::ExecLocal(std::shared_ptr infos, std::shared_ptrdestPath); } if (!infos->hasListener) { + HILOGI("No progress listener.."); return ExecCopy(infos); } auto ret = SubscribeLocalListener(infos, callback); @@ -424,6 +452,7 @@ std::shared_ptr Copy::RegisterListener(napi_env env, const std return nullptr; } jsCbMap_.insert({ *infos, callback }); + HILOGD("RegisterListener end."); return callback; } @@ -498,7 +527,6 @@ uv_work_t *Copy::GetUVwork(std::shared_ptr infos) return nullptr; } auto callback = iter->second; - infos->env = callback->env; entry = new (std::nothrow) UvEntry(iter->second, infos); if (entry == nullptr) { HILOGE("entry ptr is nullptr."); @@ -525,7 +553,11 @@ void Copy::OnFileReceive(std::shared_ptr infos) return; } uv_loop_s *loop = nullptr; - napi_get_uv_event_loop(infos->env, &loop); + napi_status status = napi_get_uv_event_loop(infos->env, &loop); + if (status != napi_ok) { + HILOGE("Failed to get uv event loop, status = %{public}d", status); + return; + } uv_queue_work( loop, work, [](uv_work_t *work) {}, reinterpret_cast(ReceiveComplete)); } @@ -686,7 +718,7 @@ std::string Copy::ConvertUriToPath(const std::string &uri) } tuple> Copy::CreateFileInfos( - const std::string &srcUri, const std::string &destUri, const NVal &listener) + const std::string &srcUri, const std::string &destUri, const NVal &listener, NVal copySignal) { auto infos = CreateSharedPtr(); if (infos == nullptr) { @@ -696,6 +728,8 @@ tuple> Copy::CreateFileInfos( infos->srcUri = srcUri; infos->destUri = destUri; infos->listener = listener; + infos->env = listener.env_; + infos->copySignal = copySignal; // todo copySignal也要绑定FileInfos,双向绑定,才能在开发者调用cancel时,知道是否绑定了拷贝任务。 infos->srcPath = ConvertUriToPath(infos->srcUri); infos->destPath = ConvertUriToPath(infos->destUri); infos->srcPath = GetRealPath(infos->srcPath); @@ -704,6 +738,13 @@ tuple> Copy::CreateFileInfos( if (listener) { infos->hasListener = true; } + if (infos->copySignal) { + HILOGI("Has copySignal."); + auto taskSignalEntity = NClass::GetEntityOf(infos->env, infos->copySignal.val_); + if (taskSignalEntity != nullptr) { + infos->taskSignal = taskSignalEntity->taskSignal; + } + } return { ERRNO_NOERR, infos }; } @@ -720,7 +761,7 @@ int Copy::ExecCopy(std::shared_ptr infos) { if (IsFile(infos->srcPath) && IsFile(infos->destPath)) { // copyFile - return CopyFile(infos->srcPath, infos->destPath); + return SendFile(infos->srcPath, infos->destPath); } if (IsDirectory(infos->srcPath) && IsDirectory(infos->destPath)) { if (infos->srcPath.back() != '/') { @@ -743,12 +784,13 @@ int Copy::ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr callback) void Copy::CopyComplete(std::shared_ptr infos, std::shared_ptr callback) { - if (callback != nullptr) { + if (callback != nullptr && infos->hasListener) { callback->progressSize = callback->totalSize; OnFileReceive(infos); } @@ -789,7 +831,14 @@ napi_value Copy::Async(napi_env env, napi_callback_info info) } auto cbExec = [infos, callback]() -> NError { if (IsRemoteUri(infos->srcUri)) { - return TransListener::CopyFileFromSoftBus(infos->srcUri, infos->destUri, std::move(callback)); + auto ret = TransListener::CopyFileFromSoftBus( + infos->srcUri, infos->destUri, infos->sessionId, std::move(callback)); + if (infos->taskSignal != nullptr) { + // todo:检视意见,这个逻辑放在上面 + infos->taskSignal->MarkRemoteTask(); + infos->taskSignal->SetSessionIdOfRemoteTask(infos->sessionId); + } + return ret; } auto result = Copy::ExecLocal(infos, callback); CloseNotifyFd(infos, callback); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index a30c42710..26ff2f75d 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -25,6 +25,8 @@ #include "common_func.h" #include "filemgmt_libn.h" #include "n_async/n_ref.h" +#include "task_signal.h" +#include "class_tasksignal/task_signal_entity.h" namespace OHOS { namespace FileManagement { @@ -32,6 +34,7 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; using namespace OHOS::AppExecFwk; +using namespace DistributedFS::ModuleTaskSignal; struct ReceiveInfo { std::string path; // dir name std::map fileList; // filename, proceededSize @@ -82,7 +85,11 @@ struct FileInfos { bool hasListener = false; napi_env env; NVal listener; + NVal copySignal; + int32_t sessionId = -1; + std::shared_ptr taskSignal = nullptr; std::set filePaths; + long checkPoint = 0; int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. bool operator==(const FileInfos &infos) const { @@ -120,6 +127,7 @@ private: // operator of napi static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg); static tuple GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg); + static tuple GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg); static void CheckOrCreatePath(const std::string &destPath); static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr &fileInfos); @@ -142,12 +150,12 @@ private: static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static tuple GetFileSize(const std::string &path); static uint64_t GetDirSize(std::shared_ptr infos, const std::string &path); - static int CopyFile(const string &src, const string &dest); + static int SendFile(const string &src, const string &dest, std::shared_ptr infos); static int MakeDir(const string &path); static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); static tuple> CreateFileInfos( - const std::string &srcUri, const std::string &destUri, const NVal &listener); + const std::string &srcUri, const std::string &destUri, const NVal &listener, NVal copySignal); static int ExecCopy(std::shared_ptr infos); // operator of file size diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp index 2d6f29800..c25fd6ec7 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp @@ -19,6 +19,7 @@ #include #include "distributed_file_daemon_manager.h" +#include "hmdfs_info.h" #include "file_uri.h" #include "ipc_skeleton.h" #include "uri.h" @@ -94,6 +95,7 @@ void TransListener::CopyDir(const std::string &path, const std::string &sandboxP NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + int &sessionId, std::shared_ptr callback) { sptr transListener = new (std::nothrow) TransListener(); @@ -102,13 +104,16 @@ NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, return NError(ENOMEM); } transListener->callback_ = std::move(callback); - auto networkId = GetNetworkIdFromUri(srcUri); - auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession(srcUri, destUri, - networkId, transListener); + Storage::DistributedFile::HmdfsInfo info{}; + info.srcUri = srcUri; + info.destUri = destUri; + info.destDeviceId = GetNetworkIdFromUri(srcUri); + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession(info, transListener); if (ret != ERRNO_NOERR) { HILOGE("PrepareSession failed, ret = %{public}d.", ret); return NError(EIO); } + sessionId = info.sessionId; std::unique_lock lock(transListener->cvMutex_); transListener->cv_.wait(lock, [&transListener]() { return transListener->copyEvent_ == SUCCESS || transListener->copyEvent_ == FAILED; diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h index b88cddf0b..0540cd8cd 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h @@ -34,6 +34,7 @@ public: int32_t OnFailed(const std::string &sessionName) override; static NError CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + int &sessionId, std::shared_ptr callback); private: diff --git a/interfaces/kits/native/BUILD.gn b/interfaces/kits/native/BUILD.gn index ceeb70833..4113da942 100644 --- a/interfaces/kits/native/BUILD.gn +++ b/interfaces/kits/native/BUILD.gn @@ -22,6 +22,14 @@ config("remote_uri_config") { ] } +config("task_signal_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "task_signal", + ] +} + ohos_shared_library("remote_uri_native") { if (!use_mingw_win && !use_mac) { stack_protector_ret = true @@ -115,10 +123,49 @@ ohos_shared_library("fileio_native") { subsystem_name = "filemanagement" } +ohos_shared_library("task_signal_native") { + if (!use_mingw_win && !use_mac) { + stack_protector_ret = true + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + } + + include_dirs = [ + "${filemanagement_service_path}/distributedfiledaemon/include/ipc", + "${filemanagement_service_path}/distributedfiledaemon/include/common", + ] + + sources = [ "task_signal/task_signal.cpp" ] + + public_configs = [ ":task_signal_config" ] + + deps = [ "${utils_path}/filemgmt_libhilog:filemgmt_libhilog" ] + + external_deps = [ + #"ability_base:zuri", + #"access_token:libaccesstoken_sdk", + "c_utils:utils", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + #"ipc:ipc_core", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "file_api" + subsystem_name = "filemanagement" +} + group("build_kits_native") { deps = [ ":environment_native", ":fileio_native", ":remote_uri_native", + ":task_signal_native" ] } diff --git a/interfaces/kits/native/task_signal/task_signal.cpp b/interfaces/kits/native/task_signal/task_signal.cpp new file mode 100644 index 000000000..3bc41fbac --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024 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 "task_signal.h" + +#include "distributed_file_daemon_manager.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +using namespace FileManagement; + +int32_t TaskSignal::Cancel() +{ + HILOGI("Cancel in."); + if (remoteTask_.load()) { + if (sessionId_ == -1) { + return -1; // 取消拷贝失败的错误码 + } + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().CancelCopyTask(sessionId_); + if (ret != 0) { // 取消拷贝失败 + HILOGI("CancelCopyTask failed, ret = %{public}d", ret); + } + return ret; + } + needCancel_.store(true); + return 0; +} + +bool TaskSignal::IsCanceled() +{ + return needCancel_.load() || remoteTask_.load(); +} + +void TaskSignal::SetTaskSignalListener(std::shared_ptr signalListener) +{ + HILOGI("SetTaskSignalListener in."); + if (signalListener_ == nullptr) { + signalListener_ = move(signalListener); + } +} + +void TaskSignal::OnCancel(const std::string &path) +{ + HILOGI("OnCancel in."); + if (signalListener_ != nullptr) { + HILOGI("OnCancel signalListener_ != nullptr."); + signalListener_->OnCancel(path); + } +} + +bool TaskSignal::CheckCancelIfNeed(const std::string &path) +{ + if (!needCancel_.load()) { + HILOGI("Do not need to cancel."); + return false; + } + HILOGI("CheckCancelIfNeed need cancel."); + OnCancel(path); + return true; +} + +void TaskSignal::MarkRemoteTask() +{ + HILOGI("MarkRemoteTask in."); + remoteTask_.store(true); +} + +void TaskSignal::SetSessionIdOfRemoteTask(int32_t sessionId) +{ + HILOGI("SetSessionIdOfRemoteTask in, sessionId = %{public}d", sessionId); + sessionId_ = sessionId; +} +} // namespace ModuleTaskSignal +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/native/task_signal/task_signal.h b/interfaces/kits/native/task_signal/task_signal.h new file mode 100644 index 000000000..9312b017d --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 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 FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H + +#include +#include + +#include "task_signal_listener.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +class TaskSignal { +public: + TaskSignal() = default; + ~TaskSignal() = default; + int32_t Cancel(); + bool IsCanceled(); + bool CheckCancelIfNeed(const std::string &path); + void OnCancel(const std::string &path); + void SetTaskSignalListener(std::shared_ptr signalListener); + void MarkRemoteTask(); + void SetSessionIdOfRemoteTask(int32_t sessionId); + std::atomic_bool needCancel_{ false }; + std::atomic_bool remoteTask_{ false }; + int32_t sessionId_ = -1; + +private: + std::shared_ptr signalListener_; +}; +} // namespace ModuleTaskSignal +} // namespace DistributedFS +} // namespace OHOS +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_H \ No newline at end of file diff --git a/interfaces/kits/native/task_signal/task_signal_listener.h b/interfaces/kits/native/task_signal/task_signal_listener.h new file mode 100644 index 000000000..32b33ca5c --- /dev/null +++ b/interfaces/kits/native/task_signal/task_signal_listener.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 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 FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H +#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H + +namespace OHOS { +namespace DistributedFS { +namespace ModuleTaskSignal { +class TaskSignalListener { +public: + virtual ~TaskSignalListener() = default; + virtual void OnCancel(const std::string &path) = 0; +}; +} // namespace ModuleTaskSignal +} // namespace DistributedFS +} // namespace OHOS +#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_LISTENER_H \ No newline at end of file diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 9da141988..b61ff4d24 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -18,5 +18,6 @@ group("unittest") { "filemgmt_libn_test:filemgmt_libn_test", "napi_test:file_api_js_test", "remote_uri:remote_uri_test", + "task_signal:task_signal_test", ] } diff --git a/interfaces/test/unittest/task_signal/BUILD.gn b/interfaces/test/unittest/task_signal/BUILD.gn new file mode 100644 index 000000000..c84f05252 --- /dev/null +++ b/interfaces/test/unittest/task_signal/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2024 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. + +import("//build/test.gni") +import("//foundation/filemanagement/file_api/file_api.gni") + +ohos_unittest("task_signal_test") { + module_out_path = "filemanagement/file_api" + + resource_config_file = "../resource/ohos_test.xml" + + sources = [ "task_signal_test.cpp" ] + + include_dirs = [ + "include", + "${file_api_path}/interfaces/kits/native/task_signal", + ] + + deps = [ + "${file_api_path}/interfaces/kits/native:task_signal_native", + "//third_party/googletest:gtest_main", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog" + ] + + external_deps = [ + #"access_token:libaccesstoken_sdk", + "c_utils:utils", + "hilog:libhilog", + #"c_utils:utilsbase", + #"ipc:ipc_core", + ] +} \ No newline at end of file diff --git a/interfaces/test/unittest/task_signal/task_signal_test.cpp b/interfaces/test/unittest/task_signal/task_signal_test.cpp new file mode 100644 index 000000000..5fc194d3a --- /dev/null +++ b/interfaces/test/unittest/task_signal/task_signal_test.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 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 "task_signal.h" + +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "task_signal_listener.h" + +namespace OHOS { +namespace DistributedFS { +using namespace std; +using namespace OHOS::DistributedFS::ModuleTaskSignal; +using namespace FileManagement; +constexpr uint32_t DEALY_TIME = 1; + +class TaskSignalTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(){}; + void SetUp(){}; + void TearDown(){}; + + static std::condition_variable taskListenerCv_; + static std::mutex taskListenerCallbackLock_; + static std::string canceledFilePath_; +}; + +std::condition_variable TaskSignalTest::taskListenerCv_; +std::mutex TaskSignalTest::taskListenerCallbackLock_; +std::string TaskSignalTest::canceledFilePath_; + +class TaskSignalListenerTestImpl : public TaskSignalListener { +public: + ~TaskSignalListenerTestImpl() = default; + void OnCancel(const std::string &path) + { + TaskSignalTest::canceledFilePath_ = path; + TaskSignalTest::taskListenerCv_.notify_one(); + HILOGI("tyx::OnCancel in. path = %{public}s", path.c_str()); + } +}; + +/** + * @tc.name: Task_Signal_Cancel_0000 + * @tc.desc: Test function of Cancel() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_Cancel_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_Cancel_0000"; + auto signal = std::make_shared(); + auto ret = signal->Cancel(); + EXPECT_TRUE(ret == 0); +} + +/** + * @tc.name: Task_Signal_IsCancel_0000 + * @tc.desc: Test function of IsCanceled() interface + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_IsCancel_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_IsCancel_0000"; + auto signal = std::make_shared(); + auto isCanceled = signal->IsCanceled(); + EXPECT_TRUE(!isCanceled); + + auto ret = signal->Cancel(); + EXPECT_TRUE(ret == 0); + isCanceled = signal->IsCanceled(); + EXPECT_TRUE(isCanceled); +} + +/** + * @tc.name: Task_Signal_SetTaskSignalListener_0000 + * @tc.desc: Test function of SetTaskSignalListener() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_SetTaskSignalListener_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_SetTaskSignalListener_0000"; + std::unique_lock lock(TaskSignalTest::taskListenerCallbackLock_); + auto signal = std::make_shared(); + auto listener = std::make_shared(); + signal->SetTaskSignalListener(listener); + std::string filePath = "aaa"; + signal->CheckCancelIfNeed(filePath); + auto cvStatus = taskListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME)); + EXPECT_NE(cvStatus, std::cv_status::timeout); + EXPECT_EQ(TaskSignalTest::canceledFilePath_, filePath); +} + +/** + * @tc.name: Task_Signal_MarkRemoteTask_0000 + * @tc.desc: Test function of SetTaskSignalListener() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NAN + */ +HWTEST_F(TaskSignalTest, Task_Signal_MarkRemoteTask_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_MarkRemoteTask_0000"; + auto signal = std::make_shared(); + signal->MarkRemoteTask(); + int sessionId = 10; + signal->SetSessionIdOfRemoteTask(sessionId); + auto ret = signal->Cancel(); + EXPECT_EQ(ret, -1); +} +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/utils/filemgmt_libn/include/n_class.h b/utils/filemgmt_libn/include/n_class.h index ca59dcc8b..7cab16f4b 100644 --- a/utils/filemgmt_libn/include/n_class.h +++ b/utils/filemgmt_libn/include/n_class.h @@ -43,13 +43,13 @@ public: template static T *GetEntityOf(napi_env env, napi_value objStat) { if (!env || !objStat) { - HILOGE("Empty input: env %d, obj %d", env == nullptr, objStat == nullptr); + HILOGE("Empty input: env %{public}d, obj %{public}d", env == nullptr, objStat == nullptr); return nullptr; } T *t = nullptr; napi_status status = napi_unwrap(env, objStat, (void **)&t); if (status != napi_ok) { - HILOGE("Cannot umwarp for pointer: %d", status); + HILOGE("Cannot umwarp for pointer: %{public}d", status); return nullptr; } return t; diff --git a/utils/filemgmt_libn/include/n_error.h b/utils/filemgmt_libn/include/n_error.h index 18d4a7384..75e09fe2c 100644 --- a/utils/filemgmt_libn/include/n_error.h +++ b/utils/filemgmt_libn/include/n_error.h @@ -36,6 +36,8 @@ constexpr int ERESTART = 85; constexpr int EDQUOT = 122; #endif constexpr int UNKROWN_ERR = -1; +constexpr int NO_TASK_ERR = -2; +constexpr int CANCEL_ERR = -3; constexpr int ERRNO_NOERR = 0; constexpr int STORAGE_SERVICE_SYS_CAP_TAG = 13600000; constexpr int FILEIO_SYS_CAP_TAG = 13900000; @@ -89,7 +91,10 @@ enum ErrCodeSuffixOfFileIO { E_DQUOT, E_UKERR, E_NOLCK, - E_NETUNREACH + E_NETUNREACH, + E_NOTASK, + E_UNCANCELED, + E_CANCELED, }; enum ErrCodeSuffixOfUserFileManager { @@ -197,6 +202,7 @@ static inline std::unordered_map uvCode2ErrCodeTable { { "ERESTART", ERESTART }, { "EDQUOT", EDQUOT }, { "ENETUNREACH", ENETUNREACH }, + { "ECANCELED", ECANCELED }, }; static inline std::unordered_map> errCodeTable { @@ -245,6 +251,10 @@ static inline std::unordered_map> errCodeTa { UNKROWN_ERR, { FILEIO_SYS_CAP_TAG + E_UKERR, "Unknown error" } }, { ENOLCK, { FILEIO_SYS_CAP_TAG + E_NOLCK, "No record locks available" } }, { ENETUNREACH, { FILEIO_SYS_CAP_TAG + E_NETUNREACH, "Network is unreachable" } }, + { NO_TASK_ERR, { FILEIO_SYS_CAP_TAG + E_NOTASK, "No task can be canceled" } }, + { CANCEL_ERR, { FILEIO_SYS_CAP_TAG + E_UNCANCELED, "Failed to cancel" } }, + { ECANCELED, { FILEIO_SYS_CAP_TAG + E_CANCELED, "Operation canceled" } }, + { ENOLCK, { FILEIO_SYS_CAP_TAG + E_NOLCK, "No record locks available" } }, { FILEIO_SYS_CAP_TAG + E_PERM, { FILEIO_SYS_CAP_TAG + E_PERM, "Operation not permitted" } }, { FILEIO_SYS_CAP_TAG + E_NOENT, { FILEIO_SYS_CAP_TAG + E_NOENT, "No such file or directory" } }, { FILEIO_SYS_CAP_TAG + E_SRCH, { FILEIO_SYS_CAP_TAG + E_SRCH, "No such process" } }, -- Gitee