From da988dca80aef40c2668ed5260758be0d3feec88 Mon Sep 17 00:00:00 2001 From: chyyy0213 Date: Fri, 5 May 2023 19:14:31 +0800 Subject: [PATCH] add scene & screen session manager Signed-off-by: chyyy0213 Change-Id: I6ee126b6694ae5e13411d8b3f27c31c172f8eb09 Signed-off-by: chyyy0213 --- bundle.json | 18 ++ window_scene/BUILD.gn | 2 + window_scene/session/BUILD.gn | 4 +- window_scene/session_manager/BUILD.gn | 28 ++- .../include/extension_session_manager.h | 3 +- .../include/scene_session_manager.h | 59 ++++++ .../include/screen_session_manager.h | 65 ++++++ .../include/session_manager_base.h | 2 +- .../src/extension_session_manager.cpp | 32 +-- .../src/scene_session_manager.cpp | 197 ++++++++++++++++++ .../src/screen_session_manager.cpp | 144 +++++++++++++ 11 files changed, 530 insertions(+), 24 deletions(-) create mode 100644 window_scene/session_manager/include/scene_session_manager.h create mode 100644 window_scene/session_manager/include/screen_session_manager.h create mode 100644 window_scene/session_manager/src/scene_session_manager.cpp create mode 100644 window_scene/session_manager/src/screen_session_manager.cpp diff --git a/bundle.json b/bundle.json index 61d983ba18..969eb5de51 100755 --- a/bundle.json +++ b/bundle.json @@ -144,6 +144,15 @@ "header_base": "//foundation/window/window_manager/window_scene" } }, + { + "type": "so", + "name": "//foundation/window/window_manager/window_scene/session:screen_session", + "header": { + "header_files": [ + ], + "header_base": "//foundation/window/window_manager/window_scene" + } + }, { "type": "so", "name": "//foundation/window/window_manager/window_scene/session_manager:scene_session_manager", @@ -152,6 +161,15 @@ ], "header_base": "//foundation/window/window_manager/window_scene" } + }, + { + "type": "so", + "name": "//foundation/window/window_manager/window_scene/session_manager:screen_session_manager", + "header": { + "header_files": [ + ], + "header_base": "//foundation/window/window_manager/window_scene" + } } ], "test": [ diff --git a/window_scene/BUILD.gn b/window_scene/BUILD.gn index 01fb8ff581..44e2e81be2 100644 --- a/window_scene/BUILD.gn +++ b/window_scene/BUILD.gn @@ -16,7 +16,9 @@ import("//build/ohos.gni") group("window_scene") { public_deps = [ "session:scene_session", + "session:screen_session", "session_manager:scene_session_manager", + "session_manager:screen_session_manager", ] } diff --git a/window_scene/session/BUILD.gn b/window_scene/session/BUILD.gn index 8ce08f99c9..d3452a26cb 100644 --- a/window_scene/session/BUILD.gn +++ b/window_scene/session/BUILD.gn @@ -55,7 +55,7 @@ ohos_shared_library("scene_session") { "ipc:ipc_single", "multimedia_image_framework:image_native", ] - + innerapi_tags = [ "platformsdk" ] part_name = "window_manager" subsystem_name = "window" } @@ -69,7 +69,7 @@ ohos_shared_library("screen_session") { public_configs = [ ":session_public_config" ] deps = [ "${graphic_base_path}/graphic_2d/rosen/modules/render_service_client:librender_service_client" ] - + innerapi_tags = [ "platformsdk" ] part_name = "window_manager" subsystem_name = "window" } diff --git a/window_scene/session_manager/BUILD.gn b/window_scene/session_manager/BUILD.gn index d7373ee00e..e36dc4a799 100644 --- a/window_scene/session_manager/BUILD.gn +++ b/window_scene/session_manager/BUILD.gn @@ -24,9 +24,10 @@ config("session_manager_public_config") { } ohos_shared_library("scene_session_manager") { - sources = [ "src/extension_session_manager.cpp" ] - - cflags_cc = [ "-std=c++17" ] + sources = [ + "src/extension_session_manager.cpp", + "src/scene_session_manager.cpp", + ] public_configs = [ ":session_manager_public_config" ] @@ -44,7 +45,28 @@ ohos_shared_library("scene_session_manager") { "eventhandler:libeventhandler", "hilog_native:libhilog", ] + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} + +ohos_shared_library("screen_session_manager") { + sources = [ "src/screen_session_manager.cpp" ] + + public_configs = [ ":session_manager_public_config" ] + + deps = [ + "${graphic_base_path}/graphic_2d/rosen/modules/render_service_client:librender_service_client", + "${window_base_path}/window_scene/common:window_scene_common", + "${window_base_path}/window_scene/session:screen_session", + ] + external_deps = [ + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog_native:libhilog", + ] + innerapi_tags = [ "platformsdk" ] part_name = "window_manager" subsystem_name = "window" } diff --git a/window_scene/session_manager/include/extension_session_manager.h b/window_scene/session_manager/include/extension_session_manager.h index 4afab00a23..0cc612c5ca 100644 --- a/window_scene/session_manager/include/extension_session_manager.h +++ b/window_scene/session_manager/include/extension_session_manager.h @@ -17,7 +17,6 @@ #define OHOS_ROSEN_WINDOW_SCENE_EXTENSION_SESSION_MANAGER_H #include -#include #include #include #include @@ -77,7 +76,7 @@ protected: virtual ~ExtensionSessionManager() = default; private: - std::map> extensionMap_; + std::map> extensionMap_; }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_WINDOW_SCENE_EXTENSION_SESSION_MANAGER_H diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h new file mode 100644 index 0000000000..1fc55d5902 --- /dev/null +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_WINDOW_SCENE_SCENE_SESSION_MANAGER_H +#define OHOS_ROSEN_WINDOW_SCENE_SCENE_SESSION_MANAGER_H + +#include "interfaces/include/ws_common.h" +#include "session/host/include/root_scene_session.h" +#include "wm_single_instance.h" + +#include "session_manager_base.h" + +namespace OHOS::Ace::NG { +class UIWindow; +} + +namespace OHOS::AAFwk { +class SessionInfo; +} + +namespace OHOS::Rosen { +class SceneSession; +class SceneSessionManager : public SessionManagerBase { +WM_DECLARE_SINGLE_INSTANCE_BASE(SceneSessionManager) +public: + sptr RequestSceneSession(const SessionInfo& sessionInfo); + WSError RequestSceneSessionActivation(const sptr& sceneSession); + WSError RequestSceneSessionBackground(const sptr& sceneSession); + WSError RequestSceneSessionDestruction(const sptr& sceneSession); + + sptr GetRootSceneSession(); + sptr GetSceneSession(uint64_t persistentId); + +protected: + SceneSessionManager(); + virtual ~SceneSessionManager() = default; + +private: + void Init(); + sptr SetAbilitySessionInfo(const sptr& scnSession); + std::map> abilitySceneMap_; + sptr rootSceneSession_; + std::shared_ptr rootScene_; +}; +} // namespace OHOS::Rosen + +#endif // OHOS_ROSEN_WINDOW_SCENE_SCENE_SESSION_MANAGER_H diff --git a/window_scene/session_manager/include/screen_session_manager.h b/window_scene/session_manager/include/screen_session_manager.h new file mode 100644 index 0000000000..b9d551ecef --- /dev/null +++ b/window_scene/session_manager/include/screen_session_manager.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_WINDOW_SCENE_SCREEN_SESSION_MANAGER_H +#define OHOS_ROSEN_WINDOW_SCENE_SCREEN_SESSION_MANAGER_H + +#include "common/include/message_scheduler.h" +#include "session/screen/include/screen_session.h" + +namespace OHOS::Rosen { +class IScreenConnectionListener : public RefBase { +public: + IScreenConnectionListener() = default; + virtual ~IScreenConnectionListener() = default; + + virtual void OnScreenConnect(sptr&) = 0; + virtual void OnScreenDisconnect(sptr&) = 0; +}; + +class RSInterfaces; + +class ScreenSessionManager : public RefBase { +public: + static ScreenSessionManager& GetInstance(); + ScreenSessionManager(const ScreenSessionManager&) = delete; + ScreenSessionManager(ScreenSessionManager&&) = delete; + ScreenSessionManager& operator=(const ScreenSessionManager&) = delete; + ScreenSessionManager& operator=(ScreenSessionManager&&) = delete; + + sptr GetScreenSession(ScreenId screenId); + + void RegisterScreenConnectionListener(sptr& screenConnectionListener); + void UnregisterScreenConnectionListener(sptr& screenConnectionListener); + +protected: + ScreenSessionManager(); + virtual ~ScreenSessionManager() = default; + +private: + void Init(); + void RegisterScreenChangeListener(); + void OnScreenChange(ScreenId screenId, ScreenEvent screenEvent); + sptr GetOrCreateScreenSession(ScreenId screenId); + + RSInterfaces& rsInterface_; + std::shared_ptr msgScheduler_ = nullptr; + std::map> screenSessionMap_; + + std::vector> screenConnectionListenerList_; +}; +} // namespace OHOS::Rosen + +#endif // OHOS_ROSEN_WINDOW_SCENE_SCREEN_SESSION_MANAGER_H diff --git a/window_scene/session_manager/include/session_manager_base.h b/window_scene/session_manager/include/session_manager_base.h index bdecef186c..993231a76a 100644 --- a/window_scene/session_manager/include/session_manager_base.h +++ b/window_scene/session_manager/include/session_manager_base.h @@ -30,7 +30,7 @@ public: return (((uint64_t)pid_ << 32) | (++sessionId_)); // 32: high bit for uint64 } protected: - std::shared_ptr mmsScheduler_ = nullptr; + std::shared_ptr msgScheduler_ = nullptr; std::atomic mmsSchedulerInit_ = false; private: int pid_ = getpid(); diff --git a/window_scene/session_manager/src/extension_session_manager.cpp b/window_scene/session_manager/src/extension_session_manager.cpp index f0a255513a..57f862d8a0 100644 --- a/window_scene/session_manager/src/extension_session_manager.cpp +++ b/window_scene/session_manager/src/extension_session_manager.cpp @@ -25,8 +25,8 @@ namespace OHOS::Rosen { namespace { - constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" }; - const std::string EXTENSION_SESSION_MANAGER_THREAD = "ExtensionSessionManager"; +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" }; +const std::string EXTENSION_SESSION_MANAGER_THREAD = "ExtensionSessionManager"; } WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager) @@ -39,12 +39,12 @@ WSError ExtensionSessionManager::Init() { WLOGFI("extension session manager init."); if (mmsSchedulerInit_) { - WLOGFW("mmsScheduler_ already init!"); + WLOGFW("msgScheduler_ already init!"); return WSError::WS_DO_NOTHING; } - mmsScheduler_ = std::make_shared(EXTENSION_SESSION_MANAGER_THREAD); - if (!mmsScheduler_) { - WLOGFE("new mmsScheduler_ failed!"); + msgScheduler_ = std::make_shared(EXTENSION_SESSION_MANAGER_THREAD); + if (!msgScheduler_) { + WLOGFE("new msgScheduler_ failed!"); return WSError::WS_ERROR_NULLPTR; } mmsSchedulerInit_ = true; @@ -69,7 +69,7 @@ sptr ExtensionSessionManager::SetAbilitySessionInfo(const sp sptr ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo) { if (!mmsSchedulerInit_) { - WLOGFE("mmsScheduler_ not init!"); + WLOGFE("msgScheduler_ not init!"); return nullptr; } auto task = [this, sessionInfo]() { @@ -85,9 +85,9 @@ sptr ExtensionSessionManager::RequestExtensionSession(const Se extensionMap_.insert({ persistentId, extensionSession }); return extensionSession; }; - // once init but mmsScheduler_ is nullptr - WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); - return mmsScheduler_->PostSyncTask(task); + // once init but msgScheduler_ is nullptr + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + return msgScheduler_->PostSyncTask(task); } WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr& extensionSession) @@ -118,8 +118,8 @@ WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptrPostAsyncTask(task); + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); return WSError::WS_OK; } @@ -147,8 +147,8 @@ WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptrMinimizeUIExtensionAbility(extSessionInfo); return WSError::WS_OK; }; - WS_CHECK_NULL_SCHE_RETURN(mmsScheduler_, task); - mmsScheduler_->PostAsyncTask(task); + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); return WSError::WS_OK; } @@ -176,8 +176,8 @@ WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptrPostAsyncTask(task); + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); return WSError::WS_OK; } } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp new file mode 100644 index 0000000000..94a39bd183 --- /dev/null +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_manager/include/scene_session_manager.h" + +#include +#include +#include +#include + +#include "common/include/message_scheduler.h" +#include "session/host/include/scene_session.h" +#include "session_info.h" +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" }; +const std::string SCENE_SESSION_MANAGER_THREAD = "SceneSessionManager"; +} + +WM_IMPLEMENT_SINGLE_INSTANCE(SceneSessionManager) +SceneSessionManager::SceneSessionManager() +{ + Init(); +} + +void SceneSessionManager::Init() +{ + WLOGFI("scene session manager init"); + msgScheduler_ = std::make_shared(SCENE_SESSION_MANAGER_THREAD); +} + +sptr SceneSessionManager::GetRootSceneSession() +{ + auto task = [this]() { + if (rootSceneSession_ != nullptr) { + return rootSceneSession_; + } + + rootSceneSession_ = new (std::nothrow) RootSceneSession(); + rootScene_ = Ace::NG::UIWindow::CreateRootScene(); + if (!rootSceneSession_ || !rootScene_) { + WLOGFE("rootSceneSession or rootScene is nullptr"); + return sptr(nullptr); + } + rootSceneSession_->SetLoadContentFunc( + [rootScene = rootScene_](const std::string& contentUrl, NativeEngine* engine, NativeValue* storage, + AbilityRuntime::Context* context) { rootScene->LoadContent(contentUrl, engine, storage, context); }); + return rootSceneSession_; + }; + + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + return msgScheduler_->PostSyncTask(task); +} + +sptr SceneSessionManager::GetSceneSession(uint64_t persistentId) +{ + auto iter = abilitySceneMap_.find(persistentId); + if (iter == abilitySceneMap_.end()) { + WLOGFE("Error found scene session with id: %{public}" PRIu64, persistentId); + return nullptr; + } + return iter->second; +} + +sptr SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo) +{ + auto task = [this, sessionInfo]() { + WLOGFI("sessionInfo: bundleName: %{public}s, abilityName: %{public}s", sessionInfo.bundleName_.c_str(), + sessionInfo.abilityName_.c_str()); + sptr sceneSession = new (std::nothrow) SceneSession(sessionInfo); + if (sceneSession == nullptr) { + WLOGFE("sceneSession is nullptr!"); + return sceneSession; + } + uint64_t persistentId = GeneratePersistentId(); + sceneSession->SetPersistentId(persistentId); + abilitySceneMap_.insert({ persistentId, sceneSession }); + WLOGFI("create session persistentId: %{public}" PRIu64 "", persistentId); + return sceneSession; + }; + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + return msgScheduler_->PostSyncTask(task); +} + +sptr SceneSessionManager::SetAbilitySessionInfo(const sptr& scnSession) +{ + sptr abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo(); + if (!abilitySessionInfo) { + WLOGFE("abilitySessionInfo is nullptr"); + return nullptr; + } + auto sessionInfo = scnSession->GetSessionInfo(); + abilitySessionInfo->sessionToken = scnSession; + abilitySessionInfo->surfaceNode = scnSession->GetSurfaceNode(); + abilitySessionInfo->callerToken = sessionInfo.callerToken_; + abilitySessionInfo->persistentId = scnSession->GetPersistentId(); + return abilitySessionInfo; +} + +WSError SceneSessionManager::RequestSceneSessionActivation(const sptr& sceneSession) +{ + wptr weakSceneSession(sceneSession); + auto task = [this, weakSceneSession]() { + auto scnSession = weakSceneSession.promote(); + if (scnSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = scnSession->GetPersistentId(); + WLOGFI("active persistentId: %{public}" PRIu64 "", persistentId); + if (abilitySceneMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + AAFwk::Want want; + auto sessionInfo = scnSession->GetSessionInfo(); + want.SetElementName(sessionInfo.bundleName_, sessionInfo.abilityName_); + AAFwk::StartOptions startOptions; + auto scnSessionInfo = SetAbilitySessionInfo(scnSession); + if (!scnSessionInfo) { + return WSError::WS_ERROR_NULLPTR; + } + // to add StartAbility + return WSError::WS_OK; + }; + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); + return WSError::WS_OK; +} + +WSError SceneSessionManager::RequestSceneSessionBackground(const sptr& sceneSession) +{ + wptr weakSceneSession(sceneSession); + auto task = [this, weakSceneSession]() { + auto scnSession = weakSceneSession.promote(); + if (scnSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = scnSession->GetPersistentId(); + WLOGFI("background session persistentId: %{public}" PRIu64 "", persistentId); + scnSession->SetActive(false); + scnSession->Background(); + if (abilitySceneMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + // to add MinimizeAbility + return WSError::WS_OK; + }; + + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); + return WSError::WS_OK; +} + +WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr& sceneSession) +{ + wptr weakSceneSession(sceneSession); + auto task = [this, weakSceneSession]() { + auto scnSession = weakSceneSession.promote(); + if (scnSession == nullptr) { + WLOGFE("session is nullptr"); + return WSError::WS_ERROR_NULLPTR; + } + auto persistentId = scnSession->GetPersistentId(); + WLOGFI("destroy session persistentId: %{public}" PRIu64 "", persistentId); + scnSession->Disconnect(); + if (abilitySceneMap_.count(persistentId) == 0) { + WLOGFE("session is invalid with %{public}" PRIu64 "", persistentId); + return WSError::WS_ERROR_INVALID_SESSION; + } + abilitySceneMap_.erase(persistentId); + + // to add TerminateAbility + return WSError::WS_OK; + }; + + WS_CHECK_NULL_SCHE_RETURN(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task); + return WSError::WS_OK; +} +} // namespace OHOS::Rosen diff --git a/window_scene/session_manager/src/screen_session_manager.cpp b/window_scene/session_manager/src/screen_session_manager.cpp new file mode 100644 index 0000000000..ed2a350be0 --- /dev/null +++ b/window_scene/session_manager/src/screen_session_manager.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_manager/include/screen_session_manager.h" + +#include +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ScreenSessionManager" }; +const std::string SCREEN_SESSION_MANAGER_THREAD = "ScreenSessionManager"; +} // namespace + +ScreenSessionManager& ScreenSessionManager::GetInstance() +{ + static ScreenSessionManager screenSessionManager; + return screenSessionManager; +} + +ScreenSessionManager::ScreenSessionManager() : rsInterface_(RSInterfaces::GetInstance()) +{ + Init(); +} + +void ScreenSessionManager::RegisterScreenConnectionListener(sptr& screenConnectionListener) +{ + if (screenConnectionListener == nullptr) { + WLOGFE("Failed to register screen connection callback, callback is null!"); + return; + } + + if (std::find(screenConnectionListenerList_.begin(), screenConnectionListenerList_.end(), + screenConnectionListener) != screenConnectionListenerList_.end()) { + WLOGFE("Repeat to register screen connection callback!"); + return; + } + + screenConnectionListenerList_.emplace_back(screenConnectionListener); + for (auto sessionIt : screenSessionMap_) { + screenConnectionListener->OnScreenConnect(sessionIt.second); + } +} + +void ScreenSessionManager::UnregisterScreenConnectionListener(sptr& screenConnectionListener) +{ + if (screenConnectionListener == nullptr) { + WLOGFE("Failed to unregister screen connection listener, listener is null!"); + return; + } + + screenConnectionListenerList_.erase( + std::remove_if(screenConnectionListenerList_.begin(), screenConnectionListenerList_.end(), + [screenConnectionListener]( + sptr listener) { return screenConnectionListener == listener; }), + screenConnectionListenerList_.end()); +} + +void ScreenSessionManager::Init() +{ + msgScheduler_ = std::make_shared(SCREEN_SESSION_MANAGER_THREAD); + RegisterScreenChangeListener(); +} + +void ScreenSessionManager::RegisterScreenChangeListener() +{ + WLOGFD("Register screen change listener."); + auto res = rsInterface_.SetScreenChangeCallback( + [this](ScreenId screenId, ScreenEvent screenEvent) { OnScreenChange(screenId, screenEvent); }); + if (res != StatusCode::SUCCESS) { + auto task = [this]() { RegisterScreenChangeListener(); }; + WS_CHECK_NULL_SCHE_VOID(msgScheduler_, task); + msgScheduler_->PostAsyncTask(task, 50); // Retry after 50 ms. + } +} + +void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenEvent) +{ + WLOGFI("On screen change. ScreenId: %{public}" PRIu64 ", ScreenEvent: %{public}d", screenId, + static_cast(screenEvent)); + auto screenSession = GetOrCreateScreenSession(screenId); + if (!screenSession) { + WLOGFE("screenSession is nullptr"); + return; + } + if (screenEvent == ScreenEvent::CONNECTED) { + for (auto listener : screenConnectionListenerList_) { + listener->OnScreenConnect(screenSession); + } + screenSession->Connect(); + } else if (screenEvent == ScreenEvent::DISCONNECTED) { + screenSession->Disconnect(); + for (auto listener : screenConnectionListenerList_) { + listener->OnScreenDisconnect(screenSession); + } + screenSessionMap_.erase(screenId); + } else { + WLOGE("Unknown ScreenEvent: %{public}d", static_cast(screenEvent)); + } +} + +sptr ScreenSessionManager::GetScreenSession(ScreenId screenId) +{ + auto iter = screenSessionMap_.find(screenId); + if (iter == screenSessionMap_.end()) { + WLOGFE("Error found screen session with id: %{public}" PRIu64, screenId); + return nullptr; + } + return iter->second; +} + +sptr ScreenSessionManager::GetOrCreateScreenSession(ScreenId screenId) +{ + auto sessionIt = screenSessionMap_.find(screenId); + if (sessionIt != screenSessionMap_.end()) { + return sessionIt->second; + } + + auto screenMode = rsInterface_.GetScreenActiveMode(screenId); + auto screenBounds = RRect({ 0, 0, screenMode.GetScreenWidth(), screenMode.GetScreenHeight() }, 0.0f, 0.0f); + ScreenProperty property; + property.SetRotation(0.0f); + property.SetBounds(screenBounds); + sptr session = new(std::nothrow) ScreenSession(screenId, property); + if (!session) { + WLOGFE("screen session is nullptr"); + return session; + } + screenSessionMap_[screenId] = session; + return session; +} +} // namespace OHOS::Rosen -- Gitee