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 a632f6f88bcf3f525da01aee43c3fec964e25f29..0080316068b5006c6e81df9c6d7830f216db9c33 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 3938f3fb85e10d82ecb19701ace14276ad983376..e27e81c2cb815527d2590d79cab064d03f02e8fc 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 cec91441f4d040c8fcdfe3c8efd4c4af5eeb1ccf..d6221d30ca707bc3e12b260f1869f6441fadfa15 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 03354dfd5c4114173ec6e27106108c6ba9b5c983..85d4d98918332f83cb598ceeddf7826de66e855b 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 0ac364b3572155a9c64cdca95ba822ea8d1d6b8b..381de256cbc86488830a601ea00230df80d7adfb 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 d27e5253882fa7fae16a068317cf914a75a03202..c2d9a0901e6528ee971efbf9ff1e541bd147c740 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 8f533889c3ee78210c3aa97f09b4b74a120da02c..e119d0011c2d940c73db325bb8385ba4488df6d4 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 89a754f6fc81de785ed58004ee86b98ec528f237..7265f74a29c842d278993be3172d48e3a18ff8d4 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 79be6423190c34796a9b015ac57405afc7f0bda5..4ae2b06f4523a738cf93f278c6c4e3b24fc8a0fc 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 4fe9fb143277d646d0823d2234785d59d43beb89..7e3093994ac264b2e023f903dfe62a4a3464a19c 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 d9b4b6ffe4608122c64ec35f99b2a6f6e1b598d2..bc2b2b4183353d048f3ace9912cd1c4745e3b4a2 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 33161108c3b9c231d61d346682654c80fc97094d..87b7fbadfd28fbe9516c2f6aae34fbc2b2894fb5 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 541cd7f6c36b055ba7f46ca5ef25f2535a66bb98..6bca55f030ae20736be1ee5a11e15c203c6b2921 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 9d2dee7980e419e59b390bd470241ac3f934ad77..a34b4dc16e23d1c7a1dde2fe18b3de04df8f5024 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 2637f4d7774448ec2606989c0646c0e80137e0f5..b0c148918368bd0c9efa388e779400deea10b1a2 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 6e832264aaceae17bf33a0678fd5dbe2c7647f43..104552554fae45a27f09cdcbc71b313327336393 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);