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 00537d1beed5c43612b0c4a9e912815746d7e230..baa8a2e0196a51f618a798a46fe88b87ec25e869 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.cpp @@ -111,7 +111,8 @@ 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"); 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 7118623aa49595f8494e2a20181bdeccf1251257..8785a6d52a4f9e64ebb66d6ab270deabf888fbf8 100644 --- a/interfaces/kits/js/src/common/ani_helper/ani_signature.h +++ b/interfaces/kits/js/src/common/ani_helper/ani_signature.h @@ -183,6 +183,7 @@ 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; }; 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 d1b34627ff68cee7f317e8631e5090fc0abe7161..5604189d7eff5740aff820c0b45398fe1b981809 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 @@ -149,10 +149,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 bf94fd6285a8ef35ed503cb5cddc519f1d98242b..81b4229488083e997f19dee100fefaf1d0aaae72 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 5bb6daff863409042cf7df87f461d6149f5bd1e2..b28b22034c257ecb22270ed7992559e0515e52c2 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,26 @@ 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,8 +57,8 @@ 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; } @@ -55,11 +73,24 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const 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 ae02a941eb6253816412bf12073cba68370c330b..ab84ded3828f54c1f49cc7f6380365d077bfe4f6 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 76bf8cd8700dafbc31b9abb6be22bf832ab0ec03..2c3e603bef0dd921a37261a16a8a4ab13f9d56cf 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() @@ -75,6 +75,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 e2e17f1c7d7f78d2ff70daed2e1d28e919a12a51..243da0b0635e2bbe9da4320718d100ab1545b3d5 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 612326ba422231742ae7c0250120114c9c30cd58..1e3cd7ec5279be5281663b5f0e68ea1d6eeb351a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -778,7 +778,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 245dff3f07feb92e9c12625585b89a3ca82f29c9..ae120c5925b56d974cffe3f14d43b38b461ac0df 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.h @@ -37,7 +37,7 @@ using namespace DistributedFS::ModuleTaskSignal; struct CopyOptions { shared_ptr progressListener; - shared_ptr copySignal; + FsTaskSignal* copySignal = nullptr; }; struct ReceiveInfo { @@ -96,7 +96,7 @@ struct FsFileInfos { bool run = true; bool hasListener = false; std::shared_ptr listener = nullptr; - std::shared_ptr taskSignal = 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 2b5266ae47a864b1b5a4bb848ee9ca59f53a577a..88e1423bbd3637fdde8304aa4e7569266aaf841e 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 @@ -535,7 +535,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);