From eac6a520b44ed09c16cbc209b38523fd139a3981 Mon Sep 17 00:00:00 2001 From: liyuke Date: Fri, 8 Aug 2025 16:44:14 +0800 Subject: [PATCH] =?UTF-8?q?copy=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liyuke Change-Id: Iac330d3708864c5d35210872e2e7fb83aa8ee34e --- .../src/common/ani_helper/ani_signature.cpp | 4 +- .../js/src/common/ani_helper/ani_signature.h | 2 + .../js/src/mod_fs/ani/bind_function_class.cpp | 3 ++ .../js/src/mod_fs/ani/ets/@ohos.file.fs.ets | 2 +- .../class_tasksignal/ani/task_signal_ani.cpp | 25 +++++++++++ .../class_tasksignal/ani/task_signal_ani.h | 1 + .../ani/task_signal_listener_ani.cpp | 41 +++++++++++++++++-- .../ani/task_signal_listener_ani.h | 8 ++-- .../ani/task_signal_wrapper.cpp | 10 ++--- .../ani/task_signal_wrapper.h | 2 +- .../class_tasksignal/fs_task_signal.cpp | 17 +++++--- .../mod_fs/class_tasksignal/fs_task_signal.h | 6 +-- .../js/src/mod_fs/properties/ani/copy_ani.cpp | 28 ++----------- .../js/src/mod_fs/properties/copy_core.cpp | 2 +- .../kits/js/src/mod_fs/properties/copy_core.h | 8 ++-- .../mod_fs/properties/copy_core_mock_test.cpp | 2 +- 16 files changed, 106 insertions(+), 55 deletions(-) diff --git a/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp b/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp index a632f6f88..008031606 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp @@ -106,7 +106,9 @@ const string FS::StreamInner::ctorSig = Builder::BuildSignatureDescriptor({ Basi // FS::TaskSignal const Type FS::TaskSignal::classType = Builder::BuildClass("@ohos.file.fs.fileIo.TaskSignal"); const string FS::TaskSignal::classDesc = FS::TaskSignal::classType.Descriptor(); -const string FS::TaskSignal::ctorSig = Builder::BuildSignatureDescriptor({ BasicTypes::longType }); +const string FS::TaskSignal::ctorDesc = Builder::BuildConstructorName(); +const string FS::TaskSignal::ctorSig = Builder::BuildSignatureDescriptor({}); +const string FS::TaskSignal::nativeTaskSignal = "nativeTaskSignal"; // FS::WatcherInner const Type FS::WatcherInner::classType = Builder::BuildClass("@ohos.file.fs.fileIo.WatcherInner"); const string FS::WatcherInner::classDesc = FS::WatcherInner::classType.Descriptor(); diff --git a/interfaces/kits/js/src/common/ani_helper/ani_signature.h b/interfaces/kits/js/src/common/ani_helper/ani_signature.h index 3938f3fb8..e27e81c2c 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.h +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.h @@ -162,7 +162,9 @@ struct StreamInner : public BaseType { struct TaskSignal : public BaseType { static const Type classType; static const string classDesc; + static const string ctorDesc; static const string ctorSig; + static const string nativeTaskSignal; }; struct WatcherInner : public BaseType { diff --git a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp index cec91441f..d6221d30c 100644 --- a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp @@ -155,10 +155,13 @@ static ani_status BindStreamMethods(ani_env *env) static ani_status BindTaskSignalClassMethods(ani_env *env) { auto classDesc = FS::TaskSignal::classDesc.c_str(); + auto ctorDesc = FS::TaskSignal::ctorDesc.c_str(); + auto ctorSig = FS::TaskSignal::ctorSig.c_str(); std::array methods = { ani_native_function { "cancel", nullptr, reinterpret_cast(TaskSignalAni::Cancel) }, ani_native_function { "onCancelNative", nullptr, reinterpret_cast(TaskSignalAni::OnCancel) }, + ani_native_function { ctorDesc, ctorSig, reinterpret_cast(TaskSignalAni::Constructor) }, }; return BindClass(env, classDesc, methods); diff --git a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets index 03354dfd5..85d4d9891 100644 --- a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets +++ b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets @@ -1254,7 +1254,7 @@ export type ProgressListener = (progress: Progress) => void; export class TaskSignal { private nativeTaskSignal: long = 0; - + native constructor(); private native onCancelNative(): void; private onCancelResolve: (path: string) => void = (path: string): void => {}; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp index 0ac364b35..381de256c 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp @@ -20,6 +20,7 @@ #include "error_handler.h" #include "filemgmt_libhilog.h" #include "fs_task_signal.h" +#include "task_signal_listener_ani.h" #include "task_signal_wrapper.h" #include "type_converter.h" @@ -30,6 +31,30 @@ namespace ANI { using namespace std; using namespace OHOS::FileManagement::ModuleFileIO; +void TaskSignalAni::Constructor(ani_env *env, ani_object signalObj) +{ + auto taskSignal = CreateSharedPtr(); + if (taskSignal == nullptr) { + HILOGE("Failed to request heap memory."); + return; + } + + ani_vm *vm = nullptr; + env->GetVM(&vm); + auto listener = CreateUniquePtr(vm, signalObj, taskSignal); + if (listener == nullptr) { + HILOGE("Failed to request heap memory."); + return ; + } + + FsResult> result = FsTaskSignal::Constructor(move(taskSignal), move(listener)); + if (!result.IsSuccess()) { + HILOGE("Failed to FsTaskSignal::Constructor"); + return ; + } + TaskSignalWrapper::Wrap(env, signalObj, move(result.GetData().value())); +} + void TaskSignalAni::Cancel(ani_env *env, [[maybe_unused]] ani_object object) { FsTaskSignal *copySignal = TaskSignalWrapper::Unwrap(env, object); diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h index d27e52538..c2d9a0901 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h @@ -25,6 +25,7 @@ namespace ANI { class TaskSignalAni final { public: + static void Constructor(ani_env *env, ani_object obj); static void Cancel(ani_env *env, [[maybe_unused]] ani_object object); static void OnCancel(ani_env *env, [[maybe_unused]] ani_object object); }; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp index 8f533889c..e119d0011 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp @@ -26,8 +26,27 @@ namespace OHOS::FileManagement::ModuleFileIO::ANI { using namespace std; using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; +bool TaskSignalListenerAni::CreateGlobalReference() +{ + if (signalRef) { + return true; + } + + ani_env *env = AniHelper::GetThreadEnv(vm); + int ret = 0; + if ((ret = env->GlobalReference_Create(static_cast(signalObj), &signalRef)) != ANI_OK) { + HILOGE("TaskSignalListenerAni GlobalReference_Create failed: %{public}d", ret); + signalRef = nullptr; + return false; + } + return true; +} + void TaskSignalListenerAni::OnCancel() { + if (!CreateGlobalReference()) { + return; + } auto filepath = taskSignal->filePath_; auto task = [this, filepath]() { SendCancelEvent(filepath); }; AniHelper::SendEventToMainThread(task); @@ -39,10 +58,11 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const HILOGE("Cannot send cancel event because the vm is null."); return; } - if (signalObj == nullptr) { - HILOGE("Cannot send cancel event because the signalObj is null."); + if (signalRef == nullptr) { + HILOGE("Cannot send cancel event because the signalRef is null."); return; } + ani_env *env = AniHelper::GetThreadEnv(vm); if (env == nullptr) { HILOGE("Cannot send cancel event because the env is null."); @@ -53,11 +73,26 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const HILOGE("Cannot convert filepath to ani string!"); return; } - auto ret = env->Object_CallMethodByName_Void(signalObj, "onCancelCallback", nullptr, aniPath); + + auto ret = env->Object_CallMethodByName_Void(static_cast(signalRef), "onCancelCallback", nullptr, + aniPath); if (ret != ANI_OK) { HILOGE("Call onCancelCallback failed, err: %{public}d", ret); return; } } +TaskSignalListenerAni::~TaskSignalListenerAni() +{ + if (signalRef == nullptr) { + return; + } + + ani_env *env = AniHelper::GetThreadEnv(vm); + int ret = 0; + if ((ret = env->GlobalReference_Delete(signalRef)) != ANI_OK) { + HILOGE("TaskSignalListenerAni GlobalReference_Delete: %{public}d", ret); + } +} + } // namespace OHOS::FileManagement::ModuleFileIO::ANI diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h index 89a754f6f..7265f74a2 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h @@ -25,20 +25,22 @@ using namespace DistributedFS::ModuleTaskSignal; class TaskSignalListenerAni : public TaskSignalListener { public: - TaskSignalListenerAni(ani_vm *vm, const ani_object &signalObj, std::shared_ptr taskSignal) - : vm(vm), signalObj(signalObj), taskSignal(taskSignal) {} + TaskSignalListenerAni(ani_vm *vm, const ani_object &signalObject, std::shared_ptr taskSignal) + : vm(vm), signalObj(signalObject), taskSignal(taskSignal) {} void OnCancel() override; public: TaskSignalListenerAni() = default; - ~TaskSignalListenerAni() = default; + ~TaskSignalListenerAni(); private: void SendCancelEvent(const std::string &filepath) const; + bool CreateGlobalReference(); private: ani_vm *vm; ani_object signalObj; + ani_ref signalRef = nullptr; std::shared_ptr taskSignal; }; diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp index 79be64231..4ae2b06f4 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp @@ -37,12 +37,12 @@ FsTaskSignal *TaskSignalWrapper::Unwrap(ani_env *env, ani_object object) HILOGE("Unwrap taskSignal obj failed! status: %{public}d", status); return nullptr; } - uintptr_t ptrValue = static_cast(nativePtr); - FsTaskSignal *copySignal = reinterpret_cast(ptrValue); + + FsTaskSignal *copySignal = reinterpret_cast(nativePtr); return copySignal; } -bool TaskSignalWrapper::Wrap(ani_env *env, ani_object object, const FsTaskSignal *signal) +bool TaskSignalWrapper::Wrap(ani_env *env, ani_object object, unique_ptr signal) { if (object == nullptr) { HILOGE("TaskSignal obj is null!"); @@ -54,14 +54,14 @@ bool TaskSignalWrapper::Wrap(ani_env *env, ani_object object, const FsTaskSignal return false; } - ani_long ptr = static_cast(reinterpret_cast(signal)); + ani_long ptr = reinterpret_cast(signal.get()); auto status = env->Object_SetFieldByName_Long(object, "nativeTaskSignal", ptr); if (status != ANI_OK) { HILOGE("Wrap taskSignal obj failed! status: %{public}d", status); return false; } - + signal.release(); return true; } diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h index 4fe9fb143..7e3093994 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h @@ -27,7 +27,7 @@ namespace ANI { class TaskSignalWrapper final { public: static FsTaskSignal *Unwrap(ani_env *env, ani_object object); - static bool Wrap(ani_env *env, ani_object object, const FsTaskSignal *signal); + static bool Wrap(ani_env *env, ani_object object, unique_ptr signal); }; } // namespace ANI diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp index d9b4b6ffe..bc2b2b418 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp @@ -24,25 +24,25 @@ namespace FileManagement { namespace ModuleFileIO { using namespace std; -FsResult> FsTaskSignal::Constructor( +FsResult> FsTaskSignal::Constructor( shared_ptr taskSignal, shared_ptr signalListener) { if (!taskSignal) { HILOGE("Invalid taskSignal"); - return FsResult>::Error(EINVAL); + return FsResult>::Error(EINVAL); } if (!signalListener) { HILOGE("Invalid signalListener"); - return FsResult>::Error(EINVAL); + return FsResult>::Error(EINVAL); } - auto copySignal = CreateSharedPtr(); + auto copySignal = CreateUniquePtr(); if (copySignal == nullptr) { HILOGE("Failed to request heap memory."); - return FsResult>::Error(ENOMEM); + return FsResult>::Error(ENOMEM); } copySignal->taskSignal_ = move(taskSignal); copySignal->signalListener_ = move(signalListener); - return FsResult>::Success(copySignal); + return FsResult>::Success(move(copySignal)); } FsResult FsTaskSignal::Cancel() @@ -74,6 +74,11 @@ shared_ptr FsTaskSignal::GetTaskSignal() const return taskSignal_; } +FsTaskSignal::FsTaskSignal() +{ + taskSignal_ = CreateSharedPtr(); +} + } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h index 33161108c..87b7fbadf 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h @@ -27,14 +27,12 @@ using namespace DistributedFS::ModuleTaskSignal; class FsTaskSignal { public: - static FsResult> Constructor( + static FsResult> Constructor( shared_ptr taskSignal, shared_ptr signalListener); FsResult Cancel(); FsResult OnCancel(); shared_ptr GetTaskSignal() const; - -public: - FsTaskSignal() = default; + FsTaskSignal(); ~FsTaskSignal() = default; FsTaskSignal(const FsTaskSignal &other) = delete; FsTaskSignal &operator=(const FsTaskSignal &other) = delete; diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp index 541cd7f6c..6bca55f03 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp @@ -81,33 +81,11 @@ static bool ParseCopySignalFromOptionArg(ani_env *env, const ani_object &options return true; } - auto taskSignal = CreateSharedPtr(); - if (taskSignal == nullptr) { - HILOGE("Failed to request heap memory."); - return false; - } - - auto signalObj = static_cast(prog); - ani_vm *vm = nullptr; - env->GetVM(&vm); - auto listener = CreateSharedPtr(vm, signalObj, taskSignal); - if (listener == nullptr) { - HILOGE("Failed to request heap memory."); - return false; - } - - auto result = FsTaskSignal::Constructor(taskSignal, listener); - if (!result.IsSuccess()) { - return false; - } - - auto copySignal = result.GetData().value(); - auto succ = TaskSignalWrapper::Wrap(env, signalObj, copySignal.get()); - if (!succ) { - return false; + FsTaskSignal *copySignal = TaskSignalWrapper::Unwrap(env, static_cast(prog)); + if (copySignal != nullptr) { + opts.copySignal = copySignal; } - opts.copySignal = move(copySignal); return true; } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp index 9d2dee798..a34b4dc16 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -776,7 +776,7 @@ tuple> CopyCore::CreateFileInfos( } auto copySignal = options.value().copySignal; if (copySignal) { - infos->taskSignal = copySignal->GetTaskSignal(); + infos->taskSignal = copySignal->GetTaskSignal().get(); } } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_core.h index 2637f4d77..b0c148918 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.h @@ -36,8 +36,8 @@ using namespace OHOS::AppExecFwk; using namespace DistributedFS::ModuleTaskSignal; struct CopyOptions { - std::shared_ptr progressListener; - std::shared_ptr copySignal; + shared_ptr progressListener; + FsTaskSignal* copySignal = nullptr; }; struct ReceiveInfo { @@ -95,8 +95,8 @@ struct FsFileInfos { int32_t eventFd = -1; bool run = true; bool hasListener = false; - std::shared_ptr listener = nullptr; - std::shared_ptr taskSignal = nullptr; + shared_ptr listener = nullptr; + TaskSignal* taskSignal = nullptr; std::set filePaths; int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. bool operator==(const FsFileInfos &infos) const diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp index 6e832264a..104552554 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -531,7 +531,7 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CreateFileInfos_001, testing::ext::T copySignal->taskSignal_ = std::make_shared(); auto options = std::make_optional(); options->progressListener = std::make_shared(); - options->copySignal = std::move(copySignal); + options->copySignal = copySignal.get(); auto [errCode, infos] = CopyCore::CreateFileInfos(srcFile, destFile, options); EXPECT_EQ(errCode, ERRNO_NOERR); -- Gitee