diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h index 6e8281d6488da0bd7128d7273c910fe057115677..e8878545cea44452989f87d0d1b9b89e6db18cbc 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h @@ -33,6 +33,7 @@ class AniWindow { public: explicit AniWindow(const sptr& window); explicit AniWindow(const std::shared_ptr& window); + ~AniWindow(); sptr GetWindow() { return windowToken_; } ani_ref GetAniRef() { return aniRef_; } void SetAniRef(const ani_ref& aniRef) { aniRef_ = aniRef; } diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp index 7f617a846dd61cfb1cf35f0ab9e412e46a3ed8cd..78daf77af381eab094e6aa4f7cf39bec0292f47b 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp @@ -46,11 +46,33 @@ namespace { /* used for free, ani has no destructor right now, only free when aniObj freed */ static std::map localObjs; } // namespace -static thread_local std::map g_aniWindowMap; +static std::mutex g_aniWindowMap_mutex; +static std::map g_aniWindowMap; AniWindow::AniWindow(const sptr& window) : windowToken_(window), registerManager_(std::make_unique()) { + NotifyNativeWinDestroyFunc func = [this](const std::string& windowName) { + { + std::lock_guard lock(g_aniWindowMap_mutex); + if (windowName.empty() || g_aniWindowMap.count(windowName) == 0) { + TLOGE(WmsLogTag::WMS_LIFE, "Can not find window %{public}s ", windowName.c_str()); + return; + } + g_aniWindowMap.erase(windowName); + TLOGI(WmsLogTag::WMS_LIFE, "Remove window %{public}s", windowName.c_str()); + } + windowToken_ = nullptr; + TLOGI(WmsLogTag::WMS_LIFE, "Destroy window %{public}s in js window", windowName.c_str()); + }; + windowToken_->RegisterWindowDestroyedListener(func); +} + +AniWindow::~AniWindow() +{ + if (windowToken_ != nullptr) { + windowToken_->UnregisterWindowDestroyedListener(); + } } AniWindow* AniWindow::GetWindowObjectFromEnv(ani_env* env, ani_object obj) @@ -1037,6 +1059,7 @@ __attribute__((no_sanitize("cfi"))) }; aniWindow->SetAniRef(ref); localObjs.insert(std::pair(ref, aniWindow.release())); + std::lock_guard lock(g_aniWindowMap_mutex); g_aniWindowMap[windowName] = ref; return obj; } @@ -2147,6 +2170,7 @@ ani_object AniWindow::SetSpecificSystemBarEnabled(ani_env* env, ani_string name, ani_ref FindAniWindowObject(const std::string& windowName) { TLOGI(WmsLogTag::DEFAULT, "[ANI] Try to find window %{public}s in g_aniWindowMap", windowName.c_str()); + std::lock_guard lock(g_aniWindowMap_mutex); if (g_aniWindowMap.find(windowName) == g_aniWindowMap.end()) { TLOGI(WmsLogTag::DEFAULT, "[ANI] Can not find window %{public}s in g_aniWindowMap", windowName.c_str()); return nullptr; @@ -2206,6 +2230,7 @@ void AniWindow::Finalizer(ani_env* env, ani_long nativeObj) if (aniWindow != nullptr) { auto window = aniWindow->GetWindow(); if (window != nullptr) { + std::lock_guard lock(g_aniWindowMap_mutex); g_aniWindowMap.erase(window->GetWindowName()); } DropWindowObjectByAni(aniWindow->GetAniRef());