diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.cpp b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.cpp index 5bbca3dd706858e26276051263e30408ab416fc8..7320a5c1e4bf69783b4d7f42f35f0ca5cbfb7f9a 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.cpp +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.cpp @@ -49,8 +49,7 @@ const std::string ON_SCREEN_CHANGE_CALLBACK = "screenModeChange"; constexpr size_t ARGC_ONE = 1; } // namespace -napi_value JsScreenSession::Create(napi_env env, const sptr& screenSession, - const ScreenEvent screenEvent) +napi_value JsScreenSession::Create(napi_env env, const sptr& screenSession) { TLOGD(WmsLogTag::DMS, "Create."); napi_value objValue = nullptr; @@ -60,7 +59,7 @@ napi_value JsScreenSession::Create(napi_env env, const sptr& scre return NapiGetUndefined(env); } - auto jsScreenSession = std::make_unique(env, screenSession, screenEvent); + auto jsScreenSession = std::make_unique(env, screenSession); napi_wrap(env, objValue, jsScreenSession.release(), JsScreenSession::Finalizer, nullptr, nullptr); napi_set_named_property(env, objValue, "screenId", CreateJsValue(env, static_cast(screenSession->GetScreenId()))); @@ -83,6 +82,8 @@ napi_value JsScreenSession::Create(napi_env env, const sptr& scre BindNativeFunction(env, objValue, "loadContent", moduleName, JsScreenSession::LoadContent); BindNativeFunction(env, objValue, "getScreenUIContext", moduleName, JsScreenSession::GetScreenUIContext); + BindNativeFunction(env, objValue, "destroyContent", moduleName, + JsScreenSession::DestroyContent); return objValue; } @@ -92,7 +93,7 @@ void JsScreenSession::Finalizer(napi_env env, void* data, void* hint) std::unique_ptr(static_cast(data)); } -JsScreenSession::JsScreenSession(napi_env env, const sptr& screenSession, const ScreenEvent screenEvent) +JsScreenSession::JsScreenSession(napi_env env, const sptr& screenSession) : env_(env), screenSession_(screenSession) { std::string name = screenSession_ ? screenSession_->GetName() : "UNKNOWN"; @@ -120,10 +121,6 @@ JsScreenSession::JsScreenSession(napi_env env, const sptr& screen OnScreenDensityChange(); }; screenSession_->SetScreenSceneDpiChangeListener(func); - if (screenEvent == ScreenEvent::DISCONNECTED) { - TLOGI(WmsLogTag::DMS, "ScreenEvent is DISCONNECTED, not set destroyFunc"); - return; - } DestroyScreenSceneFunc destroyFunc = [screenScene = screenScene_]() { if (screenScene) { screenScene->Destroy(); @@ -364,6 +361,39 @@ napi_value JsScreenSession::OnRegisterCallback(napi_env env, napi_callback_info return NapiGetUndefined(env); } +napi_value JsScreenSession::DestroyContent(napi_env env, napi_callback_info info) +{ + JsScreenSession* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnDestroyContent(env, info) : nullptr; +} + +napi_value JsScreenSession::OnDestroyContent(napi_env env, napi_callback_info info) +{ + TLOGI(WmsLogTag::DMS, "[NAPI]OnDestroyContent"); + size_t argc = 1; + napi_value argv[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc > 0) { // 0: params num + TLOGE(WmsLogTag::DMS, "Argc is invalid: %{public}zu", argc); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM))); + return NapiGetUndefined(env); + } + + if (screenScene_ == nullptr) { + TLOGE(WmsLogTag::DMS, "screenScene_ is nullptr"); + napi_throw(env, CreateJsError(env, static_cast(WmErrorCode::WM_ERROR_STATE_ABNORMALLY))); + return NapiGetUndefined(env); + } + + screenScene_->Destroy(); + TLOGI(WmsLogTag::DMS, "destroy screen scene finish"); + if (screenSession_ != nullptr) { + TLOGW(WmsLogTag::DMS, "destroy screen scene, screenId:%{public}" PRIu64 ", sessionId:%{public}" PRIu64, + screenSession_->GetScreenId(), screenSession_->GetSessionId()); + } + return NapiGetUndefined(env); +} + napi_value JsScreenSession::GetScreenUIContext(napi_env env, napi_callback_info info) { JsScreenSession* me = CheckParamsAndGetThis(env, info); diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.h b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.h index bebfa8725758d7d54b8a148246f84bbe7565ebdd..d6449e91a668f6212f206d490f8400ff89bcb6d4 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.h +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session.h @@ -26,15 +26,17 @@ namespace OHOS::Rosen { class JsScreenSession : public IScreenChangeListener { public: - JsScreenSession(napi_env env, const sptr& screenSession, const ScreenEvent screenEvent); + JsScreenSession(napi_env env, const sptr& screenSession); virtual ~JsScreenSession(); - static napi_value Create(napi_env env, const sptr& screenSession, const ScreenEvent screenEvent); + static napi_value Create(napi_env env, const sptr& screenSession); static void Finalizer(napi_env env, void* data, void* hint); private: static napi_value LoadContent(napi_env env, napi_callback_info info); napi_value OnLoadContent(napi_env env, napi_callback_info info); + static napi_value DestroyContent(napi_env env, napi_callback_info info); + napi_value OnDestroyContent(napi_env env, napi_callback_info info); napi_value ScheduleLoadContentTask(napi_env env, const std::string& contentUrl, std::weak_ptr contextWeakPtr, std::shared_ptr contentStorage); static napi_value RegisterCallback(napi_env env, napi_callback_info info); diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp index 4cce47c3db90bd54faa2c3826df6babe8f820fb8..ae6ac301d0a977b992d700db7de386f9dd2e7b1b 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp @@ -358,13 +358,13 @@ napi_value JsScreenSessionManager::GetPrimaryDisplaySystemDpi(napi_env env, napi void JsScreenSessionManager::OnScreenConnected(const sptr& screenSession) { - if (screenConnectionCallback_ == nullptr) { + if (screenConnectionCallback_ == nullptr || screenSession == nullptr) { TLOGE(WmsLogTag::DMS, "[NAPI]screenConnectionCallback is nullptr"); return; } TLOGD(WmsLogTag::DMS, "[NAPI]OnScreenConnected"); std::shared_ptr callback_ = screenConnectionCallback_; - auto asyncTask = [callback_, screenSession, env = env_]() { + auto asyncTask = [this, callback_, screenSession, env = env_]() { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsScreenSessionManager::OnScreenConnected"); napi_value objValue = nullptr; napi_create_object(env, &objValue); @@ -372,8 +372,13 @@ void JsScreenSessionManager::OnScreenConnected(const sptr& screen TLOGNE(WmsLogTag::DMS, "Object is null!"); return; } - napi_set_named_property(env, objValue, "screenSession", - JsScreenSession::Create(env, screenSession, ScreenEvent::CONNECTED)); + napi_value jsScreenSession = JsScreenSession::Create(env_, screenSession); + napi_ref ref = nullptr; + napi_create_reference(env_, jsScreenSession, 1, &ref); + jsScreenSessionMap_[screenSession->GetSessionId()] = ref; + TLOGNI(WmsLogTag::DMS, "screen connection, screenId: %{public}" PRIu64 " sessionId:%{public}" PRIu64, + screenSession->GetScreenId(), screenSession->GetSessionId()); + napi_set_named_property(env, objValue, "screenSession", jsScreenSession); napi_set_named_property(env, objValue, "screenConnectChangeType", CreateJsValue(env, 0)); napi_value argv[] = { objValue }; @@ -403,12 +408,12 @@ napi_value JsScreenSessionManager::SetCameraStatus(napi_env env, napi_callback_i void JsScreenSessionManager::OnScreenDisconnected(const sptr& screenSession) { - if (screenConnectionCallback_ == nullptr) { + if (screenConnectionCallback_ == nullptr || screenSession == nullptr) { return; } TLOGD(WmsLogTag::DMS, "[NAPI]OnScreenDisconnected"); std::shared_ptr callback_ = screenConnectionCallback_; - auto asyncTask = [callback_, screenSession, env = env_]() { + auto asyncTask = [this, callback_, screenSession, env = env_]() { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsScreenSessionManager::OnScreenDisconnected"); napi_value objValue = nullptr; napi_create_object(env, &objValue); @@ -416,8 +421,18 @@ void JsScreenSessionManager::OnScreenDisconnected(const sptr& scr TLOGNE(WmsLogTag::DMS, "Object is null!"); return; } - napi_set_named_property(env, objValue, "screenSession", - JsScreenSession::Create(env, screenSession, ScreenEvent::DISCONNECTED)); + napi_ref jsScreenSessionRef = jsScreenSessionMap_[screenSession->GetSessionId()]; + if (jsScreenSessionRef == nullptr) { + TLOGE(WmsLogTag::DMS, "js screen session ref invalid"); + return; + } + napi_value jsScreenSession; + napi_get_reference_value(env, jsScreenSessionRef, &jsScreenSession); + napi_delete_reference(env, jsScreenSessionRef); + jsScreenSessionMap_.erase(screenSession->GetScreenId()); + TLOGW(WmsLogTag::DMS, "screen disconnection, screenId: %{public}" PRIu64 "sessionId:%{public}" PRIu64, + screenSession->GetScreenId(), screenSession->GetSessionId()); + napi_set_named_property(env, objValue, "screenSession", jsScreenSession); napi_set_named_property(env, objValue, "screenConnectChangeType", CreateJsValue(env, 1)); napi_value argv[] = { objValue }; diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h index ad12b1e4d4ca41d910476cac3163663abb60971c..9a4ae099f6c8b4bd92f5933b21548b0fa6272831 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h @@ -106,6 +106,7 @@ private: std::shared_ptr screenConnectionCallback_; std::shared_ptr shutdownCallback_; napi_env env_; + std::map jsScreenSessionMap_; }; } // namespace OHOS::Rosen diff --git a/window_scene/screen_session_manager_client/include/screen_session_manager_client.h b/window_scene/screen_session_manager_client/include/screen_session_manager_client.h index 98d0f8e36e82422492b177f31e4a422e5cbccf50..3da8a70185a243995de489b3e6302abadb5302dd 100644 --- a/window_scene/screen_session_manager_client/include/screen_session_manager_client.h +++ b/window_scene/screen_session_manager_client/include/screen_session_manager_client.h @@ -18,6 +18,7 @@ #include #include +#include #include @@ -135,8 +136,8 @@ private: void ConnectToServer(); bool CheckIfNeedConnectScreen(SessionOption option); void OnScreenConnectionChanged(SessionOption option, ScreenEvent screenEvent) override; - void HandleScreenConnection(SessionOption option); - void HandleScreenDisconnection(SessionOption option); + bool HandleScreenConnection(SessionOption option); + bool HandleScreenDisconnection(SessionOption option); void NotifyClientScreenConnect(sptr& screenSession); void OnPropertyChanged(ScreenId screenId, const ScreenProperty& property, ScreenPropertyChangeReason reason) override; @@ -174,6 +175,9 @@ private: sptr displayChangeListener_; FoldDisplayMode displayMode_ = FoldDisplayMode::UNKNOWN; SuperFoldStatus currentstate_ = SuperFoldStatus::UNKNOWN; + + std::mutex screenEventMutex_; + std::unordered_set connectedScreenSet_; }; } // namespace OHOS::Rosen diff --git a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp index f4f6b8c5a819ef5edf52ded478962d864baa42f7..14f399fa1bd268195cfafc6febb1eff2c221ceb5 100644 --- a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp +++ b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp @@ -139,14 +139,49 @@ bool ScreenSessionManagerClient::CheckIfNeedConnectScreen(SessionOption option) void ScreenSessionManagerClient::OnScreenConnectionChanged(SessionOption option, ScreenEvent screenEvent) { - TLOGI(WmsLogTag::DMS, "sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64 " name: %{public}s " - "iName: %{public}s", option.screenId_, static_cast(screenEvent), option.rsId_, option.name_.c_str(), - option.innerName_.c_str()); + TLOGI(WmsLogTag::DMS, + "sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64 " name: %{public}s iName: %{public}s", + option.screenId_, static_cast(screenEvent), option.rsId_, option.name_.c_str(), option.innerName_.c_str()); + std::unique_lock lock(screenEventMutex_); + auto iter = connectedScreenSet_.find(option.screenId_); + if (iter == connectedScreenSet_.end()) { + if (screenEvent == ScreenEvent::DISCONNECTED) { + TLOGW(WmsLogTag::DMS, + "discard disconnect task, sid:%{public}" PRIu64" sEvent:%{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + return; + } + } else { + if (screenEvent == ScreenEvent::CONNECTED) { + TLOGE(WmsLogTag::DMS, + "discard connect task, sid:%{public}" PRIu64" sEvent:%{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + return; + } + } if (screenEvent == ScreenEvent::CONNECTED) { - HandleScreenConnection(option); + if (HandleScreenConnection(option)) { + connectedScreenSet_.insert(option.screenId_); + TLOGI(WmsLogTag::DMS, + "screen event wait connecting, sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + } else { + TLOGI(WmsLogTag::DMS, + "screen event not conent, sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + } } if (screenEvent == ScreenEvent::DISCONNECTED) { - HandleScreenDisconnection(option); + if (HandleScreenDisconnection(option)) { + connectedScreenSet_.erase(option.screenId_); + TLOGI(WmsLogTag::DMS, + "screen event wait disconnecting, sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + } else { + TLOGI(WmsLogTag::DMS, + "screen event not disconent, sId: %{public}" PRIu64 " sEvent: %{public}d rsId: %{public}" PRIu64, + option.screenId_, static_cast(screenEvent), option.rsId_); + } } } @@ -919,11 +954,11 @@ void ScreenSessionManagerClient::NotifyClientScreenConnect(sptr& screenSession->Connect(); } -void ScreenSessionManagerClient::HandleScreenConnection(SessionOption option) +bool ScreenSessionManagerClient::HandleScreenConnection(SessionOption option) { if (!CheckIfNeedConnectScreen(option)) { TLOGW(WmsLogTag::DMS, "no need to connect the screen"); - return; + return false; } sptr screenSession = nullptr; auto iter = screenSessionMap_.find(option.screenId_); @@ -956,14 +991,15 @@ void ScreenSessionManagerClient::HandleScreenConnection(SessionOption option) screenSession->SetIsExtend(option.isExtend_); screenSession->SetIsRealScreen(screenSessionManager_->GetIsRealScreen(option.screenId_)); NotifyClientScreenConnect(screenSession); + return true; } -void ScreenSessionManagerClient::HandleScreenDisconnection(SessionOption option) +bool ScreenSessionManagerClient::HandleScreenDisconnection(SessionOption option) { auto screenSession = GetScreenSession(option.screenId_); if (!screenSession) { TLOGE(WmsLogTag::DMS, "screenSession is null"); - return; + return false; } screenSession->DestroyScreenScene(); NotifyScreenDisconnect(screenSession); @@ -973,6 +1009,7 @@ void ScreenSessionManagerClient::HandleScreenDisconnection(SessionOption option) } TLOGW(WmsLogTag::DMS, "disconnect screenId=%{public}" PRIu64, screenSession->GetScreenId()); screenSession->Disconnect(); + return true; } bool ScreenSessionManagerClient::OnCreateScreenSessionOnly(ScreenId screenId, ScreenId rsId, diff --git a/window_scene/session/screen/include/screen_session.h b/window_scene/session/screen/include/screen_session.h index f7e7888207feab6337c4786a39a7b08ed2135d47..f9443f35f254269334ff985393e4e61b96370476 100644 --- a/window_scene/session/screen/include/screen_session.h +++ b/window_scene/session/screen/include/screen_session.h @@ -344,6 +344,7 @@ public: void SetIsAvailableAreaNeedNotify(bool isAvailableAreaNeedNotify); bool GetIsAvailableAreaNeedNotify() const; + uint64_t GetSessionId() const; /* * RS Client Multi Instance @@ -411,11 +412,14 @@ private: std::mutex isEnableCanvasRotationMutex_; bool isAvailableAreaNeedNotify_ = false; bool isSecurity_ = true; + uint64_t sessionId_; /* * RS Client Multi Instance */ std::shared_ptr rsUIDirector_; + + inline static std::atomic sessionIdGenerator_ { 0 }; }; class ScreenSessionGroup : public ScreenSession { diff --git a/window_scene/session/screen/src/screen_session.cpp b/window_scene/session/screen/src/screen_session.cpp index 8d677a59a9e5e4c856e230f16e1de8e91cc06fc3..cefc05408ee60952e27c34623c270e8634ad1fa0 100644 --- a/window_scene/session/screen/src/screen_session.cpp +++ b/window_scene/session/screen/src/screen_session.cpp @@ -68,6 +68,7 @@ ScreenSession::ScreenSession(const ScreenSessionConfig& config, ScreenSessionRea TLOGI(WmsLogTag::DMS, "[DPNODE]Config name: %{public}s, defaultId: %{public}" PRIu64", mirrorNodeId: %{public}" PRIu64"", name_.c_str(), defaultScreenId_, config.mirrorNodeId); + sessionId_ = sessionIdGenerator_++; RSAdapterUtil::InitRSUIDirector(rsUIDirector_, true, true); RSAdapterUtil::SetRSUIContext(displayNode_, GetRSUIContext(), true); Rosen::RSDisplayNodeConfig rsConfig; @@ -156,6 +157,7 @@ ScreenSession::ScreenSession(ScreenId screenId, ScreenId rsId, const std::string { TLOGI(WmsLogTag::DMS, "Success to create screenSession in constructor_0, screenid is %{public}" PRIu64"", screenId_); + sessionId_ = sessionIdGenerator_++; property_.SetRsId(rsId_); RSAdapterUtil::InitRSUIDirector(rsUIDirector_, true, true); RSAdapterUtil::SetRSUIContext(displayNode_, GetRSUIContext(), true); @@ -164,6 +166,7 @@ ScreenSession::ScreenSession(ScreenId screenId, ScreenId rsId, const std::string ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property, ScreenId defaultScreenId) : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property) { + sessionId_ = sessionIdGenerator_++; RSAdapterUtil::InitRSUIDirector(rsUIDirector_, true, true); Rosen::RSDisplayNodeConfig config = { .screenId = screenId_ }; displayNode_ = Rosen::RSDisplayNode::Create(config, GetRSUIContext()); @@ -188,6 +191,7 @@ ScreenSession::ScreenSession(ScreenId screenId, const ScreenProperty& property, NodeId nodeId, ScreenId defaultScreenId) : screenId_(screenId), defaultScreenId_(defaultScreenId), property_(property) { + sessionId_ = sessionIdGenerator_++; rsId_ = screenId; property_.SetRsId(rsId_); RSAdapterUtil::InitRSUIDirector(rsUIDirector_, true, true); @@ -477,6 +481,11 @@ bool ScreenSession::GetIsCurrentInUse() const return isInUse_; } +uint64_t ScreenSession::GetSessionId() const +{ + return sessionId_; +} + void ScreenSession::SetIsExtendVirtual(bool isExtendVirtual) { isExtendVirtual_ = isExtendVirtual;