From f67c8349b9d1edd342fef9d4d55314a5ad9fc8e0 Mon Sep 17 00:00:00 2001 From: huangji731 Date: Sat, 23 Mar 2024 20:45:21 +0800 Subject: [PATCH] https://gitee.com/openharmony/window_window_manager/issues/I9B0GE Signed-off-by: huangji731 --- dm/include/display_manager_adapter.h | 3 + dm/src/display_manager_adapter.cpp | 24 ++++ dm/src/screen_manager.cpp | 10 ++ dm/test/unittest/screen_manager_test.cpp | 32 +++++ dmserver/include/display_manager_interface.h | 11 ++ interfaces/innerkits/dm/dm_common.h | 2 + interfaces/innerkits/dm/screen.h | 6 + interfaces/innerkits/dm/screen_manager.h | 17 +++ window_scene/interfaces/include/ws_common.h | 1 + .../scene_session_manager/js_scene_utils.cpp | 1 + .../include/screen_session_manager_client.h | 1 + .../src/screen_session_manager_client.cpp | 9 ++ window_scene/session/BUILD.gn | 2 + .../session/host/include/scene_session.h | 1 + .../session/host/src/scene_session.cpp | 31 +++++ .../session/screen/include/screen_session.h | 4 + .../session/screen/src/screen_session.cpp | 13 ++ .../include/scene_session_manager.h | 1 + .../include/screen_session_manager.h | 5 +- .../zidl/screen_session_manager_proxy.h | 2 + .../src/scene_session_manager.cpp | 23 ++++ .../src/screen_session_manager.cpp | 124 +++++++++++++++++- .../src/zidl/screen_session_manager_proxy.cpp | 51 +++++++ .../src/zidl/screen_session_manager_stub.cpp | 13 ++ 24 files changed, 379 insertions(+), 8 deletions(-) diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h index 7deabacb2f..5f0c05573a 100644 --- a/dm/include/display_manager_adapter.h +++ b/dm/include/display_manager_adapter.h @@ -142,6 +142,9 @@ public: // unique screen virtual DMError MakeUniqueScreen(const std::vector& screenIds); + + virtual VirtualScreenFlag GetVirtualScreenFlag(ScreenId screenId); + virtual DMError SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag); private: static inline SingletonDelegator delegator; }; diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp index ac049c9931..ad52a141e4 100644 --- a/dm/src/display_manager_adapter.cpp +++ b/dm/src/display_manager_adapter.cpp @@ -661,4 +661,28 @@ DMError DisplayManagerAdapter::GetAvailableArea(DisplayId displayId, DMRect& are return displayManagerServiceProxy_->GetAvailableArea(displayId, area); } + +VirtualScreenFlag ScreenManagerAdapter::GetVirtualScreenFlag(ScreenId screenId) +{ + INIT_PROXY_CHECK_RETURN(VirtualScreenFlag::DEFAULT); + if (screenId == SCREEN_ID_INVALID) { + WLOGFE("screenId id is invalid"); + return VirtualScreenFlag::DEFAULT; + } + + return displayManagerServiceProxy_->GetVirtualScreenFlag(screenId); +} + +DMError ScreenManagerAdapter::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) +{ + INIT_PROXY_CHECK_RETURN(DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED); + if (screenId == SCREEN_ID_INVALID) { + WLOGFE("displayId id is invalid"); + return DMError::DM_ERROR_INVALID_PARAM; + } + if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) { + return DMError::DM_ERROR_INVALID_PARAM; + } + return displayManagerServiceProxy_->SetVirtualScreenFlag(screenId, screenFlag); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/screen_manager.cpp b/dm/src/screen_manager.cpp index a5e394d1aa..e4cc2d970a 100644 --- a/dm/src/screen_manager.cpp +++ b/dm/src/screen_manager.cpp @@ -563,6 +563,16 @@ DMError ScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, b return SingletonContainer::Get().SetVirtualMirrorScreenCanvasRotation(screenId, rotation); } +VirtualScreenFlag ScreenManager::GetVirtualScreenFlag(ScreenId screenId) +{ + return SingletonContainer::Get().GetVirtualScreenFlag(screenId); +} + +DMError ScreenManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) +{ + return SingletonContainer::Get().SetVirtualScreenFlag(screenId, screenFlag); +} + bool ScreenManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state, PowerStateChangeReason reason) { WLOGFI("screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason); diff --git a/dm/test/unittest/screen_manager_test.cpp b/dm/test/unittest/screen_manager_test.cpp index 3fbe784343..c1cc5d3550 100644 --- a/dm/test/unittest/screen_manager_test.cpp +++ b/dm/test/unittest/screen_manager_test.cpp @@ -509,6 +509,38 @@ HWTEST_F(ScreenManagerTest, RegisterVirtualScreenGroupListener02, Function | Sma result = ScreenManager::GetInstance().RegisterVirtualScreenGroupListener(listener); ASSERT_EQ(DMError::DM_OK, result); } + +/** + * @tc.name: SetVirtualScreenFlag01 + * @tc.desc: SetVirtualScreenFlag01 fun + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, SetVirtualScreenFlag01, Function | SmallTest | Level1) +{ + VirtualScreenOption defaultOption = {defaultName_, defaultWidth_, defaultHeight_, + defaultDensity_, nullptr, defaultFlags_}; + ScreenId screenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption); + DMError ret = ScreenManager::GetInstance().SetVirtualScreenFlag(screenId, VirtualScreenFlag::CAST); + ASSERT_EQ(DMError::DM_OK, ret); + ret = ScreenManager::GetInstance().DestroyVirtualScreen(screenId); + ASSERT_EQ(DMError::DM_OK, ret); +} + +/** + * @tc.name: SetVirtualScreenFlag02 + * @tc.desc: SetVirtualScreenFlag02 fun + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, SetVirtualScreenFlag02, Function | SmallTest | Level1) +{ + VirtualScreenOption defaultOption = {defaultName_, defaultWidth_, defaultHeight_, + defaultDensity_, nullptr, defaultFlags_}; + ScreenId screenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption); + DMError ret = ScreenManager::GetInstance().SetVirtualScreenFlag(screenId, VirtualScreenFlag::MAX); + ASSERT_EQ(DMError::DM_ERROR_INVALID_PARAM, ret); + ret = ScreenManager::GetInstance().DestroyVirtualScreen(screenId); + ASSERT_EQ(DMError::DM_OK, ret); +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h index a7e4e6eec2..4ce610ae4c 100644 --- a/dmserver/include/display_manager_interface.h +++ b/dmserver/include/display_manager_interface.h @@ -119,6 +119,8 @@ public: TRANS_ID_GET_AVAILABLE_AREA, TRANS_ID_NOTIFY_FOLD_TO_EXPAND_COMPLETION, TRANS_ID_CONVERT_SCREENID_TO_RSSCREENID, + TRANS_ID_GET_VIRTUAL_SCREEN_FLAG, + TRANS_ID_SET_VIRTUAL_SCREEN_FLAG, }; virtual sptr GetDefaultDisplayInfo() = 0; @@ -235,6 +237,15 @@ public: // unique screen virtual DMError MakeUniqueScreen(const std::vector& screenIds) { return DMError::DM_OK; } + + virtual VirtualScreenFlag GetVirtualScreenFlag(ScreenId screenId) + { + return VirtualScreenFlag::DEFAULT; + } + virtual DMError SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) + { + return DMError::DM_ERROR_DEVICE_NOT_SUPPORT; + } }; } // namespace OHOS::Rosen diff --git a/interfaces/innerkits/dm/dm_common.h b/interfaces/innerkits/dm/dm_common.h index 921e529aff..5121eb6f34 100644 --- a/interfaces/innerkits/dm/dm_common.h +++ b/interfaces/innerkits/dm/dm_common.h @@ -204,6 +204,7 @@ enum class ScreenChangeEvent : uint32_t { UPDATE_ROTATION, CHANGE_MODE, VIRTUAL_PIXEL_RATIO_CHANGED, + SCREEN_SWITCH_CHANGE, }; /** @@ -316,6 +317,7 @@ enum class ScreenSourceMode: uint32_t { SCREEN_MIRROR = 1, SCREEN_EXTEND = 2, SCREEN_ALONE = 3, + SCREEN_UNIQUE = 4, }; /** diff --git a/interfaces/innerkits/dm/screen.h b/interfaces/innerkits/dm/screen.h index 5d44ebf716..f246b084f4 100644 --- a/interfaces/innerkits/dm/screen.h +++ b/interfaces/innerkits/dm/screen.h @@ -39,6 +39,12 @@ struct VirtualScreenOption { std::vector missionIds_ {}; }; +enum class VirtualScreenFlag : uint32_t { + DEFAULT = 0, + CAST = 1, + MAX = 2, +}; + class Screen : public RefBase { friend class ScreenManager; public: diff --git a/interfaces/innerkits/dm/screen_manager.h b/interfaces/innerkits/dm/screen_manager.h index 6acf7a1f43..eb7149e018 100644 --- a/interfaces/innerkits/dm/screen_manager.h +++ b/interfaces/innerkits/dm/screen_manager.h @@ -295,6 +295,23 @@ public: * @return DM_OK means unregister success, others means unregister failed. */ DMError UnregisterVirtualScreenGroupListener(sptr listener); + + /** + * @brief Get virtual screen flag. + * + * @param screenId virtual screen id. + * @return virtual screen flag + */ + VirtualScreenFlag GetVirtualScreenFlag(ScreenId screenId); + + /** + * @brief Set virtual screen flag. + * + * @param screenId virtual screen id. + * @param screenFlag virtual screen flag. + * @return DM_OK means set success, others means failed. + */ + DMError SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag); private: ScreenManager(); ~ScreenManager(); diff --git a/window_scene/interfaces/include/ws_common.h b/window_scene/interfaces/include/ws_common.h index c0babfd604..4eeabc6f76 100644 --- a/window_scene/interfaces/include/ws_common.h +++ b/window_scene/interfaces/include/ws_common.h @@ -200,6 +200,7 @@ struct SessionInfo { bool isSystemInput_ = false; bool isAsyncModalBinding_ = false; bool isSetPointerAreas_ = false; + bool isCastSession_ = false; }; enum class SessionFlag : uint32_t { diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp index 7767e40fbe..60ea82cba3 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_utils.cpp @@ -645,6 +645,7 @@ napi_value CreateJsSessionInfo(napi_env env, const SessionInfo& sessionInfo) napi_set_named_property(env, objValue, "abilityName", CreateJsValue(env, sessionInfo.abilityName_)); napi_set_named_property(env, objValue, "appIndex", CreateJsValue(env, sessionInfo.appIndex_)); napi_set_named_property(env, objValue, "isSystem", CreateJsValue(env, sessionInfo.isSystem_)); + napi_set_named_property(env, objValue, "isCastSession", CreateJsValue(env, sessionInfo.isCastSession_)); napi_set_named_property(env, objValue, "persistentId", CreateJsValue(env, static_cast(sessionInfo.persistentId_))); napi_set_named_property(env, objValue, "callerPersistentId", diff --git a/window_scene/screen_session_manager/include/screen_session_manager_client.h b/window_scene/screen_session_manager/include/screen_session_manager_client.h index 8a3f944e04..63f52c6b65 100644 --- a/window_scene/screen_session_manager/include/screen_session_manager_client.h +++ b/window_scene/screen_session_manager/include/screen_session_manager_client.h @@ -66,6 +66,7 @@ public: FoldStatus GetFoldStatus(); std::shared_ptr GetScreenSnapshot(ScreenId screenId, float scaleX, float scaleY); sptr GetScreenSessionById(const ScreenId id); + ScreenId GetDefaultScreenId(); protected: ScreenSessionManagerClient() = default; diff --git a/window_scene/screen_session_manager/src/screen_session_manager_client.cpp b/window_scene/screen_session_manager/src/screen_session_manager_client.cpp index c811a06851..4cdc49f86d 100644 --- a/window_scene/screen_session_manager/src/screen_session_manager_client.cpp +++ b/window_scene/screen_session_manager/src/screen_session_manager_client.cpp @@ -361,4 +361,13 @@ sptr ScreenSessionManagerClient::GetScreenSessionById(const Scree } return iter->second; } + +ScreenId ScreenSessionManagerClient::GetDefaultScreenId() +{ + auto iter = screenSessionMap_.begin(); + if (iter != screenSessionMap_.end()) { + return iter->first; + } + return SCREEN_ID_INVALID; +} } // namespace OHOS::Rosen diff --git a/window_scene/session/BUILD.gn b/window_scene/session/BUILD.gn index 1e6c60d2d2..2d7db58257 100755 --- a/window_scene/session/BUILD.gn +++ b/window_scene/session/BUILD.gn @@ -73,6 +73,8 @@ ohos_shared_library("scene_session") { "${window_base_path}/utils:libwmutil", "${window_base_path}/window_scene/common:window_scene_common", "${window_base_path}/window_scene/intention_event/service:intention_event_anr_manager", + "${window_base_path}/window_scene/screen_session_manager:screen_session_manager_client", + "${window_base_path}/window_scene/session:screen_session", ] public_deps = diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index 53908688c2..df9403b2e0 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -279,6 +279,7 @@ private: void SetSurfaceBounds(const WSRect &rect); void UpdateWinRectForSystemBar(WSRect& rect); bool UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect); + void HandleCastScreenConnection(SessionInfo& info, sptr session); NotifySessionRectChangeFunc sessionRectChangeFunc_; static wptr enterSession_; diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index 1fd834691a..b31f80b52a 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -31,6 +31,8 @@ #include "common/include/session_permission.h" #include "interfaces/include/ws_common.h" #include "pixel_map.h" +#include "session/screen/include/screen_session.h" +#include "screen_session_manager/include/screen_session_manager_client.h" #include "session/host/include/scene_persistent_storage.h" #include "session/host/include/session_utils.h" #include "display_manager.h" @@ -39,6 +41,8 @@ #include "window_manager_hilog.h" #include "wm_math.h" #include +#include "screen_manager.h" +#include "screen.h" #include "singleton_container.h" namespace OHOS::Rosen { @@ -1977,6 +1981,7 @@ WSError SceneSession::PendingSessionActivation(const sptr ab ", windowMode: %{public}d, caller persistentId: %{public}d", info.callState_, info.persistentId_, info.callingTokenId_, info.uiAbilityId_, info.windowMode, info.callerPersistentId_); + session->HandleCastScreenConnection(info, session); if (session->pendingSessionActivationFunc_) { session->pendingSessionActivationFunc_(info); } @@ -1986,6 +1991,32 @@ WSError SceneSession::PendingSessionActivation(const sptr ab return WSError::WS_OK; } +void SceneSession::HandleCastScreenConnection(SessionInfo& info, sptr session) +{ + ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId(); + if (defScreenId == info.screenId_) { + return; + } + auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(info.screenId_); + if (flag != VirtualScreenFlag::CAST) { + return; + } + TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state :%{public}d persistentId:%{public}d", + session->GetSessionState(), info.callerPersistentId_); + if (session->GetSessionState() != SessionState::STATE_FOREGROUND && + session->GetSessionState() != SessionState::STATE_ACTIVE) { + TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state is not foreground"); + return; + } + info.isCastSession_ = true; + std::vector mirrorIds { info.screenId_ }; + Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeUniqueScreen(mirrorIds); + if (ret != Rosen::DMError::DM_OK) { + TLOGE(WmsLogTag::WMS_LIFE, "MakeUniqueScreen failed,ret: %{public}d", ret); + return; + } +} + WSError SceneSession::TerminateSession(const sptr abilitySessionInfo) { auto task = [weakThis = wptr(this), abilitySessionInfo]() { diff --git a/window_scene/session/screen/include/screen_session.h b/window_scene/session/screen/include/screen_session.h index de41fb8ac9..3ae3ac97b7 100644 --- a/window_scene/session/screen/include/screen_session.h +++ b/window_scene/session/screen/include/screen_session.h @@ -136,6 +136,9 @@ public: void SetHdrFormats(std::vector&& hdrFormats); void SetColorSpaces(std::vector&& colorSpaces); + VirtualScreenFlag GetVirtualScreenFlag(); + void SetVirtualScreenFlag(VirtualScreenFlag screenFlag); + std::string name_ { "UNKNOW" }; ScreenId screenId_ {}; ScreenId rsId_ {}; @@ -174,6 +177,7 @@ private: ScreenState screenState_ { ScreenState::INIT }; std::vector screenChangeListenerList_; ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; + VirtualScreenFlag screenFlag_ { VirtualScreenFlag::DEFAULT }; bool hasPrivateWindowForeground_ = false; std::recursive_mutex mutex_; std::function updateToInputManagerCallback_ = nullptr; diff --git a/window_scene/session/screen/src/screen_session.cpp b/window_scene/session/screen/src/screen_session.cpp index a5bc78c479..7e9deab408 100644 --- a/window_scene/session/screen/src/screen_session.cpp +++ b/window_scene/session/screen/src/screen_session.cpp @@ -360,6 +360,16 @@ void ScreenSession::SetUpdateToInputManagerCallback(std::function u updateToInputManagerCallback_ = updateToInputManagerCallback; } +VirtualScreenFlag ScreenSession::GetVirtualScreenFlag() +{ + return screenFlag_; +} + +void ScreenSession::SetVirtualScreenFlag(VirtualScreenFlag screenFlag) +{ + screenFlag_ = screenFlag; +} + void ScreenSession::UpdateToInputManager(RRect bounds, int rotation, FoldDisplayMode foldDisplayMode) { bool needUpdateToInputManager = false; @@ -575,6 +585,9 @@ ScreenSourceMode ScreenSession::GetSourceMode() const case ScreenCombination::SCREEN_ALONE: { return ScreenSourceMode::SCREEN_ALONE; } + case ScreenCombination::SCREEN_UNIQUE: { + return ScreenSourceMode::SCREEN_UNIQUE; + } default: { return ScreenSourceMode::SCREEN_ALONE; } diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 8f04a4bac7..1c631a9e57 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -557,6 +557,7 @@ private: bool GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState); WSError GetAppMainSceneSession(sptr& sceneSession, int32_t persistentId); WSError HandleSecureSessionShouldHide(const sptr& sceneSession); + void HandleCastScreenDisConnection(const sptr sceneSession); }; } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/include/screen_session_manager.h b/window_scene/session_manager/include/screen_session_manager.h index 6d2edae562..3e04b1d6ed 100644 --- a/window_scene/session_manager/include/screen_session_manager.h +++ b/window_scene/session_manager/include/screen_session_manager.h @@ -228,6 +228,8 @@ public: void NotifyAvailableAreaChanged(DMRect area); void NotifyFoldToExpandCompletion(bool foldToExpand) override; + VirtualScreenFlag GetVirtualScreenFlag(ScreenId screenId) override; + DMError SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) override; protected: ScreenSessionManager(); virtual ~ScreenSessionManager() = default; @@ -246,7 +248,8 @@ private: void CreateScreenProperty(ScreenId screenId, ScreenProperty& property); sptr GetScreenSessionInner(ScreenId screenId, ScreenProperty property); void FreeDisplayMirrorNodeInner(const sptr mirrorSession); - + DMError MirrorUniqueSwitch(const std::vector& screenIds); + void MirrorSwitchNotify(ScreenId screenId); ScreenId GetDefaultScreenId(); void NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr displayInfo, diff --git a/window_scene/session_manager/include/zidl/screen_session_manager_proxy.h b/window_scene/session_manager/include/zidl/screen_session_manager_proxy.h index c9ec95e5d2..9e427d8787 100644 --- a/window_scene/session_manager/include/zidl/screen_session_manager_proxy.h +++ b/window_scene/session_manager/include/zidl/screen_session_manager_proxy.h @@ -142,6 +142,8 @@ public: virtual DMError GetAvailableArea(DisplayId displayId, DMRect& area) override; void NotifyFoldToExpandCompletion(bool foldToExpand) override; + VirtualScreenFlag GetVirtualScreenFlag(ScreenId screenId) override; + DMError SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) override; private: static inline BrokerDelegator delegator_; }; diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 3aca8bab26..5aff2319e1 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -44,6 +44,8 @@ #include #include #include "transaction/rs_sync_transaction_controller.h" +#include "screen_manager.h" +#include "screen.h" #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE #include @@ -1559,6 +1561,7 @@ WSError SceneSessionManager::RequestSceneSessionDestruction( TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr"); return WSError::WS_ERROR_NULLPTR; } + HandleCastScreenDisConnection(scnSession); auto persistentId = scnSession->GetPersistentId(); RequestSessionUnfocus(persistentId); lastUpdatedAvoidArea_.erase(persistentId); @@ -1596,6 +1599,26 @@ WSError SceneSessionManager::RequestSceneSessionDestruction( return WSError::WS_OK; } +void SceneSessionManager::HandleCastScreenDisConnection(const sptr sceneSession) +{ + auto sessionInfo = sceneSession->GetSessionInfo(); + ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId(); + if (defScreenId == sessionInfo.screenId_) { + return; + } + auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(sessionInfo.screenId_); + if (flag != VirtualScreenFlag::CAST) { + return; + } + std::vector mirrorIds { sessionInfo.screenId_ }; + ScreenId groupId; + Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeMirror(0, mirrorIds, groupId); + if (ret != Rosen::DMError::DM_OK) { + TLOGI(WmsLogTag::WMS_LIFE, "MakeMirror failed,ret: %{public}d", ret); + return; + } +} + WSError SceneSessionManager::RequestSceneSessionDestructionInner( sptr &scnSession, sptr scnSessionInfo, const bool needRemoveSession) { diff --git a/window_scene/session_manager/src/screen_session_manager.cpp b/window_scene/session_manager/src/screen_session_manager.cpp index 1bfe816c8f..dd5cc20748 100644 --- a/window_scene/session_manager/src/screen_session_manager.cpp +++ b/window_scene/session_manager/src/screen_session_manager.cpp @@ -296,11 +296,10 @@ void ScreenSessionManager::RegisterScreenChangeListener() void ScreenSessionManager::RegisterRefreshRateModeChangeListener() { - WLOGFI("Register refreshrate mode change listener."); auto res = rsInterface_.RegisterHgmRefreshRateModeChangeCallback( [this](int32_t refreshRateMode) { OnHgmRefreshRateModeChange(refreshRateMode); }); if (res != StatusCode::SUCCESS) { - WLOGFE("Register refreshrate mode change listener failed, retry after 50 ms."); + WLOGFE("Register refresh rate mode change listener failed, retry after 50 ms."); auto task = [this]() { RegisterRefreshRateModeChangeListener(); }; taskScheduler_->PostAsyncTask(task, "RegisterRefreshRateModeChangeListener", 50); // Retry after 50 ms. } @@ -375,9 +374,15 @@ void ScreenSessionManager::OnScreenChange(ScreenId screenId, ScreenEvent screenE clientProxy_->OnScreenConnectionChanged(screenId, ScreenEvent::CONNECTED, screenSession->GetRSScreenId(), screenSession->GetName()); } + if (screenSession->GetVirtualScreenFlag() == VirtualScreenFlag::CAST) { + NotifyScreenConnected(screenSession->ConvertToScreenInfo()); + } return; } if (screenEvent == ScreenEvent::DISCONNECTED) { + if (screenSession->GetVirtualScreenFlag() == VirtualScreenFlag::CAST) { + NotifyScreenDisconnected(screenSession->GetScreenId()); + } if (phyMirrorEnable) { FreeDisplayMirrorNodeInner(screenSession); } @@ -770,6 +775,10 @@ sptr ScreenSessionManager::GetScreenSessionInner(ScreenId screenI } WLOGFI("GetScreenSessionInner: nodeId:%{public}" PRIu64 "", nodeId); session = new ScreenSession(screenId, property, nodeId, defScreenId); + session->SetVirtualScreenFlag(VirtualScreenFlag::CAST); + session->SetName("CastEngine"); + session->SetScreenCombination(ScreenCombination::SCREEN_MIRROR); + NotifyScreenChanged(session->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE); } else { session = new ScreenSession(screenId, property, defScreenId); } @@ -1764,10 +1773,8 @@ DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId) } // virtual screen destroy callback to notify scb - WLOGFI("destroy callback virtual screen"); + WLOGFI("destroy virtual screen"); OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED); - - WLOGI("DestroyVirtualScreen Enter"); std::lock_guard lock(screenSessionMapMutex_); ScreenId rsScreenId = SCREEN_ID_INVALID; screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId); @@ -1838,6 +1845,15 @@ DMError ScreenSessionManager::DisableMirror(bool disableOrNot) return DMError::DM_OK; } +void ScreenSessionManager::MirrorSwitchNotify(ScreenId screenId) +{ + auto mirrorScreen = GetScreenSession(screenId); + if (mirrorScreen != nullptr && mirrorScreen->GetVirtualScreenFlag() == VirtualScreenFlag::CAST) { + mirrorScreen->SetScreenCombination(ScreenCombination::SCREEN_MIRROR); + NotifyScreenChanged(mirrorScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE); + } +} + DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenIds, ScreenId& screenGroupId) { @@ -1850,12 +1866,20 @@ DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vectorGetVirtualScreenFlag() != VirtualScreenFlag::CAST) { + continue; + } + OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED); + } HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:MakeMirror"); auto mainScreen = GetScreenSession(mainScreenId); if (mainScreen == nullptr || allMirrorScreenIds.empty()) { @@ -1873,6 +1897,9 @@ DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vectorgroupSmsId_; + for (ScreenId screenId : allMirrorScreenIds) { + MirrorSwitchNotify(screenId); + } return DMError::DM_OK; } @@ -1928,6 +1955,85 @@ DMError ScreenSessionManager::StopScreens(const std::vector& screenIds return DMError::DM_OK; } +VirtualScreenFlag ScreenSessionManager::GetVirtualScreenFlag(ScreenId screenId) +{ + if (!SessionPermission::IsSystemCalling()) { + WLOGFE("permission denied!"); + return VirtualScreenFlag::DEFAULT; + } + auto screen = GetScreenSession(screenId); + if (screen == nullptr) { + WLOGFE("get virtual screen flag screen session null"); + return VirtualScreenFlag::DEFAULT; + } + return screen->GetVirtualScreenFlag(); +} + +DMError ScreenSessionManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) +{ + if (!SessionPermission::IsSystemCalling()) { + WLOGFE("permission denied!"); + return DMError::DM_ERROR_NOT_SYSTEM_APP; + } + if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) { + WLOGFE("set virtual screen flag range error"); + return DMError::DM_ERROR_INVALID_PARAM; + } + auto screen = GetScreenSession(screenId); + if (screen == nullptr) { + WLOGFE("set virtual screen flag screen session null"); + return DMError::DM_ERROR_INVALID_PARAM; + } + screen->SetVirtualScreenFlag(screenFlag); + return DMError::DM_OK; +} + +DMError ScreenSessionManager::MirrorUniqueSwitch(const std::vector& screenIds) +{ + WLOGFI("MirrorUniqueSwitch enter"); + auto defaultScreen = GetDefaultScreenSession(); + if (!defaultScreen) { + WLOGFE("Default screen is nullptr"); + return DMError::DM_ERROR_NULLPTR; + } + defaultScreen->groupSmsId_ = 1; + std::lock_guard lock(screenSessionMapMutex_); + auto iter = smsScreenGroupMap_.find(defaultScreen->groupSmsId_); + if (iter != smsScreenGroupMap_.end()) { + smsScreenGroupMap_.erase(iter); + } + for (ScreenId screenId : screenIds) { + auto screen = GetScreenSession(screenId); + if (screen == nullptr || screen->GetVirtualScreenFlag() != VirtualScreenFlag::CAST) { + continue; + } + OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED); + } + ScreenId uniqueScreenId = screenIds[0]; + WLOGFI("disconnect virtual screen end make unique screenId %{public}" PRIu64".", uniqueScreenId); + auto group = GetAbstractScreenGroup(defaultScreen->groupSmsId_); + if (group == nullptr) { + group = AddToGroupLocked(defaultScreen); + if (group == nullptr) { + WLOGFE("group is nullptr"); + return DMError::DM_ERROR_NULLPTR; + } + NotifyScreenGroupChanged(defaultScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP); + } + Point point; + std::vector startPoints; + startPoints.insert(startPoints.begin(), screenIds.size(), point); + ChangeScreenGroup(group, screenIds, startPoints, true, ScreenCombination::SCREEN_UNIQUE); + auto uniqueScreen = GetScreenSession(uniqueScreenId); + if (uniqueScreen != nullptr && uniqueScreen->GetVirtualScreenFlag() == VirtualScreenFlag::CAST) { + uniqueScreen->SetScreenCombination(ScreenCombination::SCREEN_UNIQUE); + NotifyScreenChanged(uniqueScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE); + } + // virtual screen create callback to notify scb + OnVirtualScreenChange(uniqueScreenId, ScreenEvent::CONNECTED); + return DMError::DM_OK; +} + DMError ScreenSessionManager::MakeUniqueScreen(const std::vector& screenIds) { if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) { @@ -1939,12 +2045,17 @@ DMError ScreenSessionManager::MakeUniqueScreen(const std::vector& scre WLOGFE("MakeUniqueScreen screen is empty"); return DMError::DM_ERROR_INVALID_PARAM; } + ScreenId uniqueScreenId = screenIds[0]; + auto uniqueScreen = GetScreenSession(uniqueScreenId); + if (uniqueScreen != nullptr && uniqueScreen->GetVirtualScreenFlag() == VirtualScreenFlag::CAST) { + return MirrorUniqueSwitch(screenIds); + } for (auto screenId : screenIds) { ScreenId rsScreenId = SCREEN_ID_INVALID; bool res = ConvertScreenIdToRsScreenId(screenId, rsScreenId); WLOGFI("unique screenId: %{public}" PRIu64" rsScreenId: %{public}" PRIu64"", screenId, rsScreenId); if (!res) { - WLOGFE("convert screenid to rsScreenId failed"); + WLOGFE("convert screenId to rsScreenId failed"); continue; } auto screenSession = GetScreenSession(screenId); @@ -1964,7 +2075,6 @@ DMError ScreenSessionManager::MakeUniqueScreen(const std::vector& scre return DMError::DM_OK; } - DMError ScreenSessionManager::MakeExpand(std::vector screenId, std::vector startPoint, ScreenId& screenGroupId) diff --git a/window_scene/session_manager/src/zidl/screen_session_manager_proxy.cpp b/window_scene/session_manager/src/zidl/screen_session_manager_proxy.cpp index 83a748ad16..225b535278 100644 --- a/window_scene/session_manager/src/zidl/screen_session_manager_proxy.cpp +++ b/window_scene/session_manager/src/zidl/screen_session_manager_proxy.cpp @@ -2166,4 +2166,55 @@ void ScreenSessionManagerProxy::NotifyFoldToExpandCompletion(bool foldToExpand) return; } } + +VirtualScreenFlag ScreenSessionManagerProxy::GetVirtualScreenFlag(ScreenId screenId) +{ + if (screenId == SCREEN_ID_INVALID) { + return VirtualScreenFlag::DEFAULT; + } + MessageOption option(MessageOption::TF_SYNC); + MessageParcel reply; + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return VirtualScreenFlag::DEFAULT; + } + if (!data.WriteUint64(screenId)) { + WLOGFE("Write screenId failed"); + return VirtualScreenFlag::DEFAULT; + } + if (Remote()->SendRequest(static_cast(DisplayManagerMessage::TRANS_ID_GET_VIRTUAL_SCREEN_FLAG), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return VirtualScreenFlag::DEFAULT; + } + return static_cast(reply.ReadUint32()); +} + +DMError ScreenSessionManagerProxy::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag) +{ + if (screenId == SCREEN_ID_INVALID) { + return DMError::DM_ERROR_INVALID_PARAM; + } + if (screenFlag < VirtualScreenFlag::DEFAULT || screenFlag >= VirtualScreenFlag::MAX) { + return DMError::DM_ERROR_INVALID_PARAM; + } + MessageOption option(MessageOption::TF_ASYNC); + MessageParcel reply; + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED; + } + if (!data.WriteUint64(screenId) || !data.WriteUint32(static_cast(screenFlag))) { + WLOGFE("Write screenId or screenFlag failed"); + return DMError::DM_ERROR_WRITE_DATA_FAILED; + } + if (Remote()->SendRequest(static_cast(DisplayManagerMessage::TRANS_ID_SET_VIRTUAL_SCREEN_FLAG), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + return DMError::DM_ERROR_IPC_FAILED; + } + return static_cast(reply.ReadInt32()); +} } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/src/zidl/screen_session_manager_stub.cpp b/window_scene/session_manager/src/zidl/screen_session_manager_stub.cpp index 54c3f10f96..1059d599ee 100644 --- a/window_scene/session_manager/src/zidl/screen_session_manager_stub.cpp +++ b/window_scene/session_manager/src/zidl/screen_session_manager_stub.cpp @@ -652,6 +652,19 @@ int32_t ScreenSessionManagerStub::OnRemoteRequest(uint32_t code, MessageParcel& NotifyFoldToExpandCompletion(foldToExpand); break; } + case DisplayManagerMessage::TRANS_ID_GET_VIRTUAL_SCREEN_FLAG: { + ScreenId screenId = static_cast(data.ReadUint64()); + VirtualScreenFlag screenFlag = GetVirtualScreenFlag(screenId); + reply.WriteUint32(static_cast(screenFlag)); + break; + } + case DisplayManagerMessage::TRANS_ID_SET_VIRTUAL_SCREEN_FLAG: { + ScreenId screenId = static_cast(data.ReadUint64()); + VirtualScreenFlag screenFlag = static_cast(data.ReadUint32()); + DMError setRet = SetVirtualScreenFlag(screenId, screenFlag); + reply.WriteInt32(static_cast(setRet)); + break; + } default: WLOGFW("unknown transaction code"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); -- Gitee