diff --git a/interfaces/kits/js/ani/file_cloud_sync/include/download_callback_middle_ani.h b/interfaces/kits/js/ani/file_cloud_sync/include/download_callback_middle_ani.h index 95cb07e9d96910828c1047a08167c56211b511d0..5de35db52e455689b31200c37023deb33688f351 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/include/download_callback_middle_ani.h +++ b/interfaces/kits/js/ani/file_cloud_sync/include/download_callback_middle_ani.h @@ -31,9 +31,10 @@ class CloudDlCallbackMiddleAni : public CloudDownloadCallback, public RegisterCallbackManagerAni, public std::enable_shared_from_this { public: - virtual ~CloudDlCallbackMiddleAni() = default; + ~CloudDlCallbackMiddleAni() override = default; void OnDownloadProcess(const DownloadProgressObj &progress) override; void RemoveDownloadInfo(int64_t downloadId); + void TryCleanCallback(); protected: std::vector GetDownloadIdsByUri(const std::string &uri); diff --git a/interfaces/kits/js/ani/file_cloud_sync/include/register_callback_manager_ani.h b/interfaces/kits/js/ani/file_cloud_sync/include/register_callback_manager_ani.h index 109db2704ce12fa027b299341a0a8bbe7ebcec84..b25919e24b2dd4608278fd41c3eaa9026c03c643 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/include/register_callback_manager_ani.h +++ b/interfaces/kits/js/ani/file_cloud_sync/include/register_callback_manager_ani.h @@ -32,6 +32,10 @@ public: void OnJsCallback(ani_env *env, ani_object value, uint32_t argc); ani_env *GetEnv(); void DetachEnv(); + virtual ~RegisterCallbackManagerAni(); + +protected: + void CleanAllCallback(bool force); protected: ani_vm *vm_{nullptr}; diff --git a/interfaces/kits/js/ani/file_cloud_sync/src/cloud_download_ani.cpp b/interfaces/kits/js/ani/file_cloud_sync/src/cloud_download_ani.cpp index ac26f622fb9f2832f2e88ff8c07a02bc376f2d39..9de13f75d5d2268d9e15d6e25fbf1177a7e7ec32 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/src/cloud_download_ani.cpp +++ b/interfaces/kits/js/ani/file_cloud_sync/src/cloud_download_ani.cpp @@ -167,6 +167,7 @@ void CloudDownloadAni::DownloadOff0(ani_env *env, ani_object object, ani_string ErrorHandler::Throw(env, JsErrCode::E_IPCSS); return; } + callbackImpl->TryCleanCallback(); } void CloudDownloadAni::DownloadOff1(ani_env *env, ani_object object, ani_string evt) diff --git a/interfaces/kits/js/ani/file_cloud_sync/src/cloud_file_cache_ani.cpp b/interfaces/kits/js/ani/file_cloud_sync/src/cloud_file_cache_ani.cpp index ed76c059862226d43854d4cfe19f98315cfcb7bf..edb257fba90532d104047870b155353c33846794 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/src/cloud_file_cache_ani.cpp +++ b/interfaces/kits/js/ani/file_cloud_sync/src/cloud_file_cache_ani.cpp @@ -148,6 +148,7 @@ void CloudFileCacheAni::CloudFileCacheOff0(ani_env *env, ani_object object, ani_ ErrorHandler::Throw(env, JsErrCode::E_IPCSS); return; } + callbackImpl->TryCleanCallback(); } void CloudFileCacheAni::CloudFileCacheOff1(ani_env *env, ani_object object, ani_string evt) diff --git a/interfaces/kits/js/ani/file_cloud_sync/src/download_callback_middle_ani.cpp b/interfaces/kits/js/ani/file_cloud_sync/src/download_callback_middle_ani.cpp index 06e6362eb2b86f7163b226ef065057aedcc5f664..8eb816af3ce737e3903ef535be6081a51fb3e79a 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/src/download_callback_middle_ani.cpp +++ b/interfaces/kits/js/ani/file_cloud_sync/src/download_callback_middle_ani.cpp @@ -97,4 +97,16 @@ void CloudDlCallbackMiddleAni::OnDownloadProcess(const DownloadProgressObj &prog LOGE("failed to send event"); } } + +void CloudDlCallbackMiddleAni::TryCleanCallback() +{ + bool noTask = false; + { + std::lock_guard lock(downloadInfoMtx_); + noTask = (downloadInfos_.size() == 0); + } + if (noTask) { + CleanAllCallback(false); + } +} } // namespace OHOS::FileManagement::CloudSync \ No newline at end of file diff --git a/interfaces/kits/js/ani/file_cloud_sync/src/register_callback_manager_ani.cpp b/interfaces/kits/js/ani/file_cloud_sync/src/register_callback_manager_ani.cpp index 7b1dae0e8693cb50e01ce463d33b0546da3554a1..7f3ab975d271dc058fe848d0e2d7eb8095ff400e 100644 --- a/interfaces/kits/js/ani/file_cloud_sync/src/register_callback_manager_ani.cpp +++ b/interfaces/kits/js/ani/file_cloud_sync/src/register_callback_manager_ani.cpp @@ -54,7 +54,7 @@ ani_status RegisterCallbackManagerAni::RegisterCallback(ani_env *env, ani_object ani_status RegisterCallbackManagerAni::UnregisterCallback(ani_env *env, ani_object callback) { - if (validRefNum_ == 0) { + if (validRefNum_.load() == 0) { return ANI_OK; } std::lock_guard lock(callbackMtx_); @@ -163,4 +163,34 @@ void RegisterCallbackManagerAni::DetachEnv() LOGE("detach current env failed, err: %{private}d", ret); } } + +RegisterCallbackManagerAni::~RegisterCallbackManagerAni() +{ + CleanAllCallback(true); +} + +void RegisterCallbackManagerAni::CleanAllCallback(bool force) +{ + std::lock_guard lock(callbackMtx_); + if (!force) { + if (validRefNum_.load() != 0) { + return; + } + } + ani_env *env = GetEnv(); + if (env != nullptr) { + for (auto &iter : callbackList_) { + env->GlobalReference_Delete(iter.second); + } + } else { + LOGE("Failed to delete reference before clean callback"); + } + if (callbackList_.size() != 0) { + DetachEnv(); + } + + callbackList_.clear(); + validRefNum_ = 0; + LOGI("Clean all callback, valid callback count is 0"); +} } // namespace OHOS::FileManagement::CloudSync \ No newline at end of file diff --git a/interfaces/kits/js/cloudfilesync/cloud_file_cache_napi.cpp b/interfaces/kits/js/cloudfilesync/cloud_file_cache_napi.cpp index b3f80f7fd8cd980d6afa5c4859e658950bfa98a9..9f2c50177f976064a8626a883cf73e1403560a84 100644 --- a/interfaces/kits/js/cloudfilesync/cloud_file_cache_napi.cpp +++ b/interfaces/kits/js/cloudfilesync/cloud_file_cache_napi.cpp @@ -560,6 +560,7 @@ napi_value CloudFileCacheNapi::Off(napi_env env, napi_callback_info info) NError(JsErrCode::E_INNER_FAILED).ThrowErr(env); return nullptr; } + callbackImpl->TryCleanCallback(); return NVal::CreateUndefined(env).val_; } diff --git a/interfaces/kits/js/cloudfilesync/cloud_file_napi.cpp b/interfaces/kits/js/cloudfilesync/cloud_file_napi.cpp index cd5c1a3edba79a21e8f0830f2d18f9353862f3c8..a4a344e4fbe8655975452af5c5b2e6139f1bd4ad 100644 --- a/interfaces/kits/js/cloudfilesync/cloud_file_napi.cpp +++ b/interfaces/kits/js/cloudfilesync/cloud_file_napi.cpp @@ -232,6 +232,7 @@ napi_value CloudFileDownloadNapi::Off(napi_env env, napi_callback_info info) NError(JsErrCode::E_IPCSS).ThrowErr(env); return nullptr; } + callbackImpl->TryCleanCallback(); return NVal::CreateUndefined(env).val_; } diff --git a/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.cpp b/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.cpp index 13623fb2e67be5fee58447bac00e2253652f9ca4..535c3d5489a852fb3f32def9523bec01d7a3ea03 100644 --- a/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.cpp +++ b/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.cpp @@ -94,4 +94,16 @@ void CloudDlCallbackMiddleNapi::OnDownloadProcess(const DownloadProgressObj &pro LOGE("Failed to execute libuv work queue, status: %{public}d", status); } } + +void CloudDlCallbackMiddleNapi::TryCleanCallback() +{ + bool noTask = false; + { + std::lock_guard lock(downloadInfoMtx_); + noTask = (downloadInfos_.size() == 0); + } + if (noTask) { + CleanAllCallback(false); + } +} } // namespace OHOS::FileManagement::CloudSync \ No newline at end of file diff --git a/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.h b/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.h index 2937215a1ec7681fd445849e11de2a20a67d42b9..045642060cd663d81f10cd71ea4317de4a8a52ce 100644 --- a/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.h +++ b/interfaces/kits/js/cloudfilesync/download_callback_middle_napi.h @@ -32,9 +32,10 @@ class CloudDlCallbackMiddleNapi : public CloudDownloadCallback, public std::enable_shared_from_this { public: explicit CloudDlCallbackMiddleNapi(napi_env env) : RegisterCallbackManagerNapi(env) {} - virtual ~CloudDlCallbackMiddleNapi() = default; + ~CloudDlCallbackMiddleNapi() override = default; void OnDownloadProcess(const DownloadProgressObj &progress) override; void RemoveDownloadInfo(int64_t downloadId); + void TryCleanCallback(); protected: virtual void DownloadProgressInner(std::shared_ptr progress){}; diff --git a/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.cpp b/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.cpp index fb86d62613a64a2bce3f967a165f9112a8277b28..8b90bd6bb498bb70221d7b3926f03b4750b20781 100644 --- a/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.cpp +++ b/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.cpp @@ -44,7 +44,7 @@ napi_status RegisterCallbackManagerNapi::RegisterCallback(napi_value callback) napi_status RegisterCallbackManagerNapi::UnregisterCallback(napi_value callback) { - if (validRefNum_ == 0) { + if (validRefNum_.load() == 0) { return napi_ok; } std::lock_guard lock(callbackMtx_); @@ -80,7 +80,6 @@ napi_status RegisterCallbackManagerNapi::UnregisterCallback(napi_value callback) } LOGI("After unregister, callback list size: %{public}zu, validRefNum_=%{public}d", callbackList_.size(), validRefNum_.load()); - return napi_ok; } @@ -132,4 +131,26 @@ void RegisterCallbackManagerNapi::OnJsCallback(napi_value *value, uint32_t argc) iter++; } } + +RegisterCallbackManagerNapi::~RegisterCallbackManagerNapi() +{ + CleanAllCallback(true); +} + +void RegisterCallbackManagerNapi::CleanAllCallback(bool force) +{ + std::lock_guard lock(callbackMtx_); + if (!force) { + if (validRefNum_.load() != 0) { + return; + } + } + + for (auto &iter : callbackList_) { + napi_delete_reference(env_, iter.second); + } + callbackList_.clear(); + validRefNum_ = 0; + LOGI("Clean all callback, valid callback count is 0"); +} } // namespace OHOS::FileManagement::CloudSync \ No newline at end of file diff --git a/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.h b/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.h index 1c1df12e01919b552850c98d7476085df1e8ef80..ef17923a923bbbae524199d788ff0dfac85184b0 100644 --- a/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.h +++ b/interfaces/kits/js/cloudfilesync/register_callback_manager_napi.h @@ -30,6 +30,10 @@ public: napi_status RegisterCallback(napi_value callback); napi_status UnregisterCallback(napi_value callback); void OnJsCallback(napi_value *value, uint32_t argc); + virtual ~RegisterCallbackManagerNapi(); + +protected: + void CleanAllCallback(bool force); protected: napi_env env_;