diff --git a/window_scene/screen_session_manager/include/screen_session_manager.h b/window_scene/screen_session_manager/include/screen_session_manager.h index 25da9bc1152a8576b4ce7e1db9f3df03a1e25c6c..ae96947003e8a1315ebbbbe2d1d7852ae13adbb6 100644 --- a/window_scene/screen_session_manager/include/screen_session_manager.h +++ b/window_scene/screen_session_manager/include/screen_session_manager.h @@ -481,6 +481,7 @@ public: bool SynchronizePowerStatus(ScreenPowerState state) override; std::shared_ptr GetPowerTaskScheduler() const; bool GetCancelSuspendStatus() const; + void RemoveScreenCastInfo(ScreenId screenId); protected: ScreenSessionManager(); @@ -836,6 +837,13 @@ private: void SwitchModeHandleExternalScreen(bool isSwitchToPcMode); void WaitUpdateAvailableAreaForPc(); + std::unordered_map> screenCastInfoMap_; + std::shared_mutex screenCastInfoMapMutex_; + bool HasSameScreenCastInfo(ScreenId screenId, ScreenId castScreenId, ScreenCombination screenCombination); + void SetScreenCastInfo(ScreenId screenId, ScreenId castScreenId, ScreenCombination screenCombination); + void ChangeMirrorScreenConfig(sptr group, + DMRect& mainScreenRegion, sptr screen); + LowTempMode lowTemp_ {LowTempMode::UNKNOWN}; std::mutex lowTempMutex_; std::mutex pcModeSwitchMutex_; diff --git a/window_scene/screen_session_manager/src/multi_screen_manager.cpp b/window_scene/screen_session_manager/src/multi_screen_manager.cpp index dbda07d82278af41315bb0d96e8a6a8d98928023..f5916f573b20aa28e6a6f7dca684f9a5b12425ca 100644 --- a/window_scene/screen_session_manager/src/multi_screen_manager.cpp +++ b/window_scene/screen_session_manager/src/multi_screen_manager.cpp @@ -133,6 +133,10 @@ DMError MultiScreenManager::PhysicalScreenMirrorSwitch(const std::vectorSetMirrorScreenRegion(defaultSession->GetRSScreenId(), mirrorRegion); screenSession->SetIsPhysicalMirrorSwitch(true); screenSession->SetScreenCombination(ScreenCombination::SCREEN_MIRROR); + ScreenSessionManager::GetInstance().NotifyScreenChanged( + screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE); + ScreenSessionManager::GetInstance().NotifyDisplayChanged( + screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::SOURCE_MODE_CHANGED); } TLOGW(WmsLogTag::DMS, "physical screen switch to mirror end"); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:PhysicalScreenMirrorSwitch end"); @@ -154,6 +158,11 @@ DMError MultiScreenManager::PhysicalScreenUniqueSwitch(const std::vectorReuseDisplayNode(config); screenSession->SetVirtualPixelRatio(screenSession->GetScreenProperty().GetDefaultDensity()); ScreenSessionManager::GetInstance().OnVirtualScreenChange(physicalScreenId, ScreenEvent::CONNECTED); + ScreenSessionManager::GetInstance().RemoveScreenCastInfo(physicalScreenId); + ScreenSessionManager::GetInstance().NotifyScreenChanged( + screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE); + ScreenSessionManager::GetInstance().NotifyDisplayChanged( + screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::SOURCE_MODE_CHANGED); } TLOGW(WmsLogTag::DMS, "end"); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:PhysicalScreenUniqueSwitch end"); @@ -190,9 +199,12 @@ DMError MultiScreenManager::VirtualScreenUniqueSwitch(sptr screen auto uniqueScreen = ScreenSessionManager::GetInstance().GetScreenSession(uniqueScreenId); if (uniqueScreen != nullptr) { uniqueScreen->SetScreenCombination(ScreenCombination::SCREEN_UNIQUE); + ScreenSessionManager::GetInstance().NotifyDisplayChanged(uniqueScreen->ConvertToDisplayInfo(), + DisplayChangeEvent::SOURCE_MODE_CHANGED); ScreenSessionManager::GetInstance().NotifyScreenChanged(uniqueScreen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SWITCH_CHANGE); } + ScreenSessionManager::GetInstance().RemoveScreenCastInfo(uniqueScreenId); // virtual screen create callback to notify scb ScreenSessionManager::GetInstance().OnVirtualScreenChange(uniqueScreenId, ScreenEvent::CONNECTED); } diff --git a/window_scene/screen_session_manager/src/screen_session_manager.cpp b/window_scene/screen_session_manager/src/screen_session_manager.cpp index 66e98b6ebac8def0649acbb9ff57b0d0c9ca9af8..f4c94486d9ee295f59ea4f8a27c07e003f15fd87 100644 --- a/window_scene/screen_session_manager/src/screen_session_manager.cpp +++ b/window_scene/screen_session_manager/src/screen_session_manager.cpp @@ -1510,6 +1510,7 @@ void ScreenSessionManager::HandleScreenDisconnectEvent(sptr scree TLOGE(WmsLogTag::DMS, "screenSession is nullptr"); return; } + RemoveScreenCastInfo(screenId); if (g_isPcDevice) { ScreenId rsId = screenSession->GetRSScreenId(); if (screenId != rsId && screenSession->GetScreenProperty().GetScreenType() == ScreenType::REAL) { @@ -5074,6 +5075,7 @@ DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId) } screenSessionMap_.erase(screenId); } + RemoveScreenCastInfo(screenId); NotifyScreenDisconnected(screenId); if (auto clientProxy = GetClientProxy()) { clientProxy->OnVirtualScreenDisconnected(rsScreenId); @@ -6048,6 +6050,10 @@ void ScreenSessionManager::ChangeScreenGroup(sptr group, con } TLOGI(WmsLogTag::DMS, "Screen->groupSmsId_: %{public}" PRIu64"", screen->groupSmsId_); screen->groupSmsId_ = 1; + if (!HasSameScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination)) { + TLOGI(WmsLogTag::DMS, "has not same cast info"); + filterScreen = false; + } if (filterScreen && screen->groupSmsId_ == group->screenId_ && group->HasChild(screen->screenId_)) { // screen already in group if (combination != ScreenCombination::SCREEN_MIRROR || @@ -6068,25 +6074,71 @@ void ScreenSessionManager::ChangeScreenGroup(sptr group, con removeChildResMap[screenId] = originGroup != nullptr; addScreens.emplace_back(screenId); if (combination == ScreenCombination::SCREEN_MIRROR) { - auto mirrorScreenId = group->mirrorScreenId_; - ScreenId rsScreenId = SCREEN_ID_INVALID; - if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) { - TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId); - } else { - screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion); - screen->SetIsPhysicalMirrorSwitch(false); - IsEnableRegionRotation(screen); - TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}" - PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u", - screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_, - mainScreenRegion.width_, mainScreenRegion.height_); - } + ChangeMirrorScreenConfig(group, mainScreenRegion, screen); } + NotifyScreenChanged(screen->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE); + NotifyDisplayChanged(screen->ConvertToDisplayInfo(), DisplayChangeEvent::SOURCE_MODE_CHANGED); + SetScreenCastInfo(screen->GetScreenId(), group->mirrorScreenId_, combination); } group->combination_ = combination; AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap); } +void ScreenSessionManager::ChangeMirrorScreenConfig(sptr group, + DMRect& mainScreenRegion, sptr screen) +{ + if (screen == nullptr) { + return; + } + auto screenId = screen->GetScreenId(); + auto mirrorScreenId = group->mirrorScreenId_; + ScreenId rsScreenId = SCREEN_ID_INVALID; + if (!ConvertScreenIdToRsScreenId(screenId, rsScreenId)) { + TLOGE(WmsLogTag::DMS, "Screen: %{public}" PRIu64" convert to rs id failed", mirrorScreenId); + return; + } + screen->SetMirrorScreenRegion(rsScreenId, mainScreenRegion); + screen->SetIsPhysicalMirrorSwitch(false); + IsEnableRegionRotation(screen); + TLOGI(WmsLogTag::DMS, "Screen: %{public}" PRIu64" mirror to %{public}" + PRIu64" with region, x:%{public}d y:%{public}d w:%{public}u h:%{public}u", + screenId, mirrorScreenId, mainScreenRegion.posX_, mainScreenRegion.posY_, + mainScreenRegion.width_, mainScreenRegion.height_); +} + +bool ScreenSessionManager::HasSameScreenCastInfo(ScreenId screenId, + ScreenId castScreenId, ScreenCombination screenCombination) +{ + std::shared_lock lock(screenCastInfoMapMutex_); + auto iter = screenCastInfoMap_.find(screenId); + if (iter != screenCastInfoMap_.end() && screenCastInfoMap_[screenId].first == castScreenId && + screenCastInfoMap_[screenId].second == screenCombination) { + return true; + } + return false; +} + +void ScreenSessionManager::SetScreenCastInfo(ScreenId screenId, + ScreenId castScreenId, ScreenCombination screenCombination) +{ + std::unique_lock lock(screenCastInfoMapMutex_); + screenCastInfoMap_[screenId] = std::make_pair(castScreenId, screenCombination); + TLOGI(WmsLogTag::DMS, + "screenId:%{public}" PRIu64 ",castScreenId:%{public}" PRIu64 ",screenCombination:%{public}d", + screenId, castScreenId, screenCombination); +} + +void ScreenSessionManager::RemoveScreenCastInfo(ScreenId screenId) +{ + std::unique_lock lock(screenCastInfoMapMutex_); + auto iter = screenCastInfoMap_.find(screenId); + if (iter == screenCastInfoMap_.end()) { + return; + } + screenCastInfoMap_.erase(iter); + TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 "", screenId); +} + void ScreenSessionManager::IsEnableRegionRotation(sptr screenSession) { if (!FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()) { @@ -9538,6 +9590,9 @@ DMError ScreenSessionManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId return DMError::DM_OK; } SetMultiScreenModeInner(mainScreenId, secondaryScreenId, screenMode); + auto combination = screenMode == MultiScreenMode::SCREEN_MIRROR ? + ScreenCombination::SCREEN_MIRROR : ScreenCombination::SCREEN_EXPAND; + SetScreenCastInfo(secondaryScreenId, mainScreenId, combination); NotifyScreenModeChange(); #endif return DMError::DM_OK; diff --git a/window_scene/test/dms_unittest/screen_session_manager_test2.cpp b/window_scene/test/dms_unittest/screen_session_manager_test2.cpp index b6d0bc89c1fbec7a7f25a44e162fe43363745fd7..d7d9926409166d6c0680b1b628bf5f84a7b23c7d 100644 --- a/window_scene/test/dms_unittest/screen_session_manager_test2.cpp +++ b/window_scene/test/dms_unittest/screen_session_manager_test2.cpp @@ -43,7 +43,7 @@ namespace { void MyLogCallback(const LogType type, const LogLevel level, const unsigned int domain, const char* tag, const char* msg) { - g_errLog = msg; + g_errLog += msg; } } class ScreenSessionManagerTest : public testing::Test { @@ -1273,6 +1273,118 @@ HWTEST_F(ScreenSessionManagerTest, GetCancelSuspendStatus04, TestSize.Level1) ssm_->sessionDisplayPowerController_->canceledSuspend_ = true; EXPECT_TRUE(ssm_->GetCancelSuspendStatus()); } + +/** + * @tc.name: HasSameScreenCastInfo + * @tc.desc: HasSameScreenCastInfo + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, HasSameScreenCastInfo01, TestSize.Level1) { + ASSERT_NE(ssm_, nullptr); + ScreenId screenId = 1660; + ScreenId mainScreenId = 0; + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); + ssm_->SetScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR); + EXPECT_TRUE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); + ssm_->RemoveScreenCastInfo(screenId); + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); +} + +/** + * @tc.name: HasSameScreenCastInfo + * @tc.desc: HasSameScreenCastInfo + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, HasSameScreenCastInfo02, TestSize.Level1) { + ASSERT_NE(ssm_, nullptr); + ScreenId screenId = 1660; + ScreenId mainScreenId1 = 0; + ScreenId mainScreenId2 = 1; + ssm_->SetScreenCastInfo(screenId, mainScreenId1, ScreenCombination::SCREEN_MIRROR); + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(mainScreenId1, mainScreenId2, ScreenCombination::SCREEN_MIRROR)); + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId2, ScreenCombination::SCREEN_MIRROR)); + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId1, ScreenCombination::SCREEN_EXPAND)); + EXPECT_TRUE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId1, ScreenCombination::SCREEN_MIRROR)); + ssm_->RemoveScreenCastInfo(screenId); +} + +/** + * @tc.name: RemoveScreenCastInfo + * @tc.desc: RemoveScreenCastInfo + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, RemoveScreenCastInfo, TestSize.Level1) { + ASSERT_NE(ssm_, nullptr); + ScreenId screenId = 1660; + ScreenId mainScreenId = 0; + ScreenId screenIdNotExist = 1080; + ssm_->SetScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR); + EXPECT_TRUE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); + ssm_->RemoveScreenCastInfo(screenIdNotExist); + EXPECT_TRUE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); + ssm_->RemoveScreenCastInfo(screenId); + EXPECT_FALSE(ssm_->HasSameScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR)); +} + +/** + * @tc.name: ChangeScreenGroup + * @tc.desc: ChangeScreenGroup test screenCastInfo has same + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, ChangeScreenGroup, TestSize.Level1) { + ASSERT_NE(ssm_, nullptr); + g_errLog.clear(); + LOG_SetCallback(MyLogCallback); + ScreenId groupId = 1; + ScreenId screenId = 4080; + ScreenId mainScreenId = 0; + sptr group = + sptr::MakeSptr(groupId, SCREEN_ID_INVALID, "test", ScreenCombination::SCREEN_MIRROR); + group->mirrorScreenId_ = mainScreenId; + sptr screenSession = sptr::MakeSptr(screenId, ScreenProperty(), 0); + ssm_->screenSessionMap_[screenId] = screenSession; + std::vector screens; + screens.emplace_back(screenId); + DMRect region = { 0, 0, 1, 1 }; + Point point; + std::vector startPoints; + startPoints.insert(startPoints.begin(), screens.size(), point); + ssm_->ChangeScreenGroup(group, screens, startPoints, true, ScreenCombination::SCREEN_MIRROR, region); + EXPECT_TRUE(g_errLog.find("has not same cast info") != std::string::npos); + g_errLog.clear(); + ssm_->SetScreenCastInfo(screenId, mainScreenId, ScreenCombination::SCREEN_MIRROR); + ssm_->ChangeScreenGroup(group, screens, startPoints, true, ScreenCombination::SCREEN_MIRROR, region); + EXPECT_FALSE(g_errLog.find("has not same cast info") != std::string::npos); + g_errLog.clear(); + ssm_->RemoveScreenCastInfo(screenId); +} + +/** + * @tc.name: ChangeMirrorScreenConfig + * @tc.desc: ChangeMirrorScreenConfig + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, ChangeMirrorScreenConfig, TestSize.Level1) { + ASSERT_NE(ssm_, nullptr); + g_errLog.clear(); + LOG_SetCallback(MyLogCallback); + ScreenId groupId = 1; + ScreenId screenId = 4080; + ScreenId mainScreenId = 0; + sptr group = + sptr::MakeSptr(groupId, SCREEN_ID_INVALID, "test", ScreenCombination::SCREEN_MIRROR); + sptr screenSession = sptr::MakeSptr(screenId, ScreenProperty(), 0); + ssm_->screenSessionMap_[screenId] = screenSession; + group->mirrorScreenId_ = mainScreenId; + DMRect region = { 0, 0, 1, 1 }; + ssm_->ChangeMirrorScreenConfig(group, region, screenSession); + EXPECT_TRUE(g_errLog.find("convert to rs id failed") != std::string::npos); + g_errLog.clear(); + ssm_->screenIdManager_.UpdateScreenId(screenId, screenId); + ssm_->ChangeMirrorScreenConfig(group, region, screenSession); + EXPECT_TRUE(g_errLog.find("with region") != std::string::npos); + g_errLog.clear(); +} } } } \ No newline at end of file