diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 4404a0a425593cb16b0458892bd38d31da4623c4..2fab87697c26e5fdc0dd2dbefe165d5fac307dde 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -607,6 +607,10 @@ void DisplayManagerService::UpdateRSTree(DisplayId displayId, DisplayId parentDi DMError DisplayManagerService::AddSurfaceNodeToDisplay(DisplayId displayId, std::shared_ptr& surfaceNode, bool onTop) { + if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) { + TLOGE(WmsLogTag::DMS, "Permission denied!"); + return DMError::DM_ERROR_NOT_SYSTEM_APP; + } TLOGI(WmsLogTag::DMS, "DisplayId: %{public}" PRIu64 ", onTop: %{public}d", displayId, onTop); if (surfaceNode == nullptr) { TLOGW(WmsLogTag::DMS, "Surface is null"); @@ -619,6 +623,10 @@ DMError DisplayManagerService::AddSurfaceNodeToDisplay(DisplayId displayId, DMError DisplayManagerService::RemoveSurfaceNodeFromDisplay(DisplayId displayId, std::shared_ptr& surfaceNode) { + if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) { + TLOGE(WmsLogTag::DMS, "Permission denied!"); + return DMError::DM_ERROR_NOT_SYSTEM_APP; + } TLOGI(WmsLogTag::DMS, "DisplayId: %{public}" PRIu64, displayId); if (surfaceNode == nullptr) { TLOGW(WmsLogTag::DMS, "Surface is null"); 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 b1b3e6a180c71ec7c5ec6063e7a279c8ebf97d10..4059f7ed0bcd871f4f2cac192d4757304f29153e 100644 --- a/window_scene/screen_session_manager/include/screen_session_manager.h +++ b/window_scene/screen_session_manager/include/screen_session_manager.h @@ -675,6 +675,7 @@ private: std::mutex lastStatusUpdateMutex_; mutable std::recursive_mutex screenSessionMapMutex_; + std::mutex screenAgentMapMutex_; std::map> screenSessionMap_; mutable std::recursive_mutex physicalScreenSessionMapMutex_; std::map> physicalScreenSessionMap_; @@ -748,6 +749,7 @@ private: int32_t screenOnDelay_ {0}; std::vector mirrorScreenIds_; + std::mutex mirrorScreenIdsMutex_; std::mutex snapBypickerMutex_; std::mutex switchUserMutex_; std::condition_variable switchUserCV_; 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 054158447d221dec82d79a6ae82f00f804eb801f..ddbd2661551a0d9a2f3e7b89fcc021aac32af5af 100644 --- a/window_scene/screen_session_manager/src/screen_session_manager.cpp +++ b/window_scene/screen_session_manager/src/screen_session_manager.cpp @@ -596,7 +596,10 @@ void ScreenSessionManager::ConfigureScreenScene() Orientation orientation = static_cast(numbersConfig["buildInDefaultOrientation"][0]); TLOGD(WmsLogTag::DMS, "orientation = %{public}d", orientation); } - allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig(); + { + std::lock_guard lock(allDisplayPhysicalResolutionMutex_); + allDisplayPhysicalResolution_ = ScreenSceneConfig::GetAllDisplayPhysicalConfig(); + } } void ScreenSessionManager::ConfigureDpi() @@ -1103,18 +1106,21 @@ void ScreenSessionManager::SetMultiScreenDefaultRelativePosition() MultiScreenPositionOptions extendOptions; sptr mainSession = nullptr; sptr extendSession = nullptr; - for (auto sessionIt : screenSessionMap_) { - auto screenSession = sessionIt.second; - if (screenSession == nullptr) { - TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64, - sessionIt.first); - continue; - } - if (screenSession->GetIsRealScreen()) { - if (screenSession->GetIsExtend() && extendSession == nullptr) { - extendSession = screenSession; - } else { - mainSession = screenSession; + { + std::lock_guard lock(screenSessionMapMutex_); + for (auto sessionIt : screenSessionMap_) { + auto screenSession = sessionIt.second; + if (screenSession == nullptr) { + TLOGI(WmsLogTag::DMS, "screenSession is nullptr, ScreenId: %{public}" PRIu64, + sessionIt.first); + continue; + } + if (screenSession->GetIsRealScreen()) { + if (screenSession->GetIsExtend() && extendSession == nullptr) { + extendSession = screenSession; + } else { + mainSession = screenSession; + } } } } @@ -1339,20 +1345,23 @@ void ScreenSessionManager::UnregisterSettingWireCastObserver(ScreenId screenId) if (g_isPcDevice) { return; } - for (const auto& sessionIt : screenSessionMap_) { - auto screenSession = sessionIt.second; - if (screenSession == nullptr) { - TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first); - continue; - } - bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId()); - if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) { - TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first); - continue; - } - if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR && - screenSession->GetScreenId() != screenId) { - return; + { + std::lock_guard lock(screenSessionMapMutex_); + for (const auto& sessionIt : screenSessionMap_) { + auto screenSession = sessionIt.second; + if (screenSession == nullptr) { + TLOGE(WmsLogTag::DMS, "screenSession is nullptr, screenId:%{public}" PRIu64"", sessionIt.first); + continue; + } + bool phyMirrorEnable = IsDefaultMirrorMode(screenSession->GetScreenId()); + if (screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL || !phyMirrorEnable) { + TLOGE(WmsLogTag::DMS, "screen is not real or external, screenId:%{public}" PRIu64"", sessionIt.first); + continue; + } + if (screenSession ->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR && + screenSession->GetScreenId() != screenId) { + return; + } } } ScreenSettingHelper::UnregisterSettingWireCastObserver(); @@ -2776,10 +2785,13 @@ sptr ScreenSessionManager::GetOrCreateScreenSession(ScreenId scre return screenSession; } - if (g_isPcDevice && phyScreenPropMap_.size() > 1) { - // pc is none, pad&&phone is mirror - TLOGW(WmsLogTag::DMS, "Only Support one External screen."); - return nullptr; + if (g_isPcDevice) { + std::lock_guard lock_phy(phyScreenPropMapMutex_); + if (phyScreenPropMap_.size() > 1) { + // pc is none, pad&&phone is mirror + TLOGW(WmsLogTag::DMS, "Only Support one External screen."); + return nullptr; + } } screenIdManager_.UpdateScreenId(screenId, screenId); @@ -3290,6 +3302,10 @@ void ScreenSessionManager::BlockScreenOffByCV(void) bool ScreenSessionManager::TryToCancelScreenOff() { std::lock_guard notifyLock(sessionDisplayPowerController_->notifyMutex_); + if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) { + TLOGE(WmsLogTag::DMS, "Permission denied!"); + return false; + } TLOGI(WmsLogTag::DMS, "[UL_POWER]about to cancel suspend, can:%{public}d, got:%{public}d, need:%{public}d", sessionDisplayPowerController_->canCancelSuspendNotify_, gotScreenOffNotify_, needScreenOffNotify_); if (sessionDisplayPowerController_->canCancelSuspendNotify_) { @@ -4669,7 +4685,7 @@ void ScreenSessionManager::AddVirtualScreenDeathRecipient(const sptr& agent) { OnRemoteDied(agent); }); } - std::lock_guard lock(screenSessionMapMutex_); + std::lock_guard lock(screenAgentMapMutex_); if (deathRecipient_ != nullptr) { auto agIter = screenAgentMap_.find(displayManagerAgent); if (agIter == screenAgentMap_.end()) { @@ -4943,7 +4959,7 @@ DMError ScreenSessionManager::DestroyVirtualScreen(ScreenId screenId) OnVirtualScreenChange(screenId, ScreenEvent::DISCONNECTED); ScreenId rsScreenId = SCREEN_ID_INVALID; { - std::lock_guard lock(screenSessionMapMutex_); + std::lock_guard lock(screenAgentMapMutex_); screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId); for (auto &agentIter : screenAgentMap_) { auto iter = std::find(agentIter.second.begin(), agentIter.second.end(), screenId); @@ -5120,7 +5136,10 @@ DMError ScreenSessionManager::MakeMirror(ScreenId mainScreenId, std::vector& mirrorScreenIds) { - mirrorScreenIds_ = mirrorScreenIds; + { + std::lock_guard lock(mirrorScreenIdsMutex_); + mirrorScreenIds_ = mirrorScreenIds; + } TLOGI(WmsLogTag::DMS, "Register Setting cast Observer"); SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { SetCastFromSettingData(); }; ScreenSettingHelper::RegisterSettingCastObserver(updateFunc); @@ -5136,7 +5155,13 @@ void ScreenSessionManager::SetCastFromSettingData() } else { TLOGI(WmsLogTag::DMS, "get setting cast success, enable: %{public}u", enable); } - for (ScreenId screenId : mirrorScreenIds_) { + + std::vector mirrorScreenIdsCopy; + { + std::lock_guard lock(mirrorScreenIdsMutex_); + mirrorScreenIdsCopy = mirrorScreenIds_; + } + for (ScreenId screenId : mirrorScreenIdsCopy) { ScreenId rsScreenId; if (!screenIdManager_.ConvertToRsScreenId(screenId, rsScreenId)) { TLOGE(WmsLogTag::DMS, "No corresponding rsId"); @@ -6450,27 +6475,29 @@ bool ScreenSessionManager::OnRemoteDied(const sptr& agent) if (agent == nullptr) { return false; } - auto agentIter = screenAgentMap_.find(agent); - if (agentIter != screenAgentMap_.end()) { - while (screenAgentMap_[agent].size() > 0) { - auto diedId = screenAgentMap_[agent][0]; - auto screenSession = GetScreenSession(diedId); - if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) { - std::vector screenIds; - screenIds.emplace_back(diedId); - TLOGI(WmsLogTag::DMS, "stop mirror in OnRemoteDied: %{public}" PRIu64, diedId); - StopMirror(screenIds); - } - TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64, diedId); - DMError res = DestroyVirtualScreen(diedId); - if (res != DMError::DM_OK) { - TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64, diedId); - return false; - } + std::vector screenVecCopy; + { + std::lock_guard lock(screenAgentMapMutex_); + auto agentIter = screenAgentMap_.find(agent); + if (agentIter != screenAgentMap_.end()) { + screenVecCopy = agentIter->second; } - screenAgentMap_.erase(agent); } - return true; + bool ret = true; + for (const auto screenId : screenVecCopy) { + auto screenSession = GetScreenSession(screenId); + if (screenSession && screenSession->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) { + TLOGI(WmsLogTag::DMS, "stop mirror in OnRemoteDied: %{public}" PRIu64, screenId); + StopMirror(std::vector(1, screenId)); + } + TLOGI(WmsLogTag::DMS, "destroy screenId in OnRemoteDied: %{public}" PRIu64, screenId); + DMError res = DestroyVirtualScreen(screenId); + if (res != DMError::DM_OK) { + TLOGE(WmsLogTag::DMS, "destroy failed in OnRemoteDied: %{public}" PRIu64, screenId); + ret = false; + } + } + return ret; } std::vector ScreenSessionManager::GetAllValidScreenIds(const std::vector& screenIds) const @@ -8610,9 +8637,15 @@ int ScreenSessionManager::Dump(int fd, const std::vector& args) TLOGE(WmsLogTag::DMS, "dumper is nullptr"); return -1; } - dumper->DumpFreezedPidList(freezedPidList_); + { + std::lock_guard lock(freezedPidListMutex_); + dumper->DumpFreezedPidList(freezedPidList_); + } dumper->DumpEventTracker(screenEventTracker_); - dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_); + { + std::lock_guard lock(oldScbPidsMutex_); + dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_); + } dumper->ExecuteDumpCmd(); TLOGI(WmsLogTag::DMS, "dump end"); return 0; @@ -10347,10 +10380,14 @@ sptr ScreenSessionManager::GetScreenSessionByRsId(ScreenId rsScre sptr ScreenSessionManager::GetPhysicalScreenSession(ScreenId screenId) const { - std::lock_guard lock(physicalScreenSessionMapMutex_); - if (screenSessionMap_.empty()) { - screenEventTracker_.LogWarningAllInfos(); + { + std::lock_guard lock(screenSessionMapMutex_); + if (screenSessionMap_.empty()) { + screenEventTracker_.LogWarningAllInfos(); + } } + + std::lock_guard lock(physicalScreenSessionMapMutex_); auto iter = physicalScreenSessionMap_.find(screenId); if (iter == physicalScreenSessionMap_.end()) { TLOGW(WmsLogTag::DMS, "not found screen id: %{public}" PRIu64, screenId); diff --git a/window_scene/session/screen/include/screen_session.h b/window_scene/session/screen/include/screen_session.h index 6188c04a638e1361a0484a358ea8992f6d1ddb19..345b4b4b2d33e41087c81678e4a398b60f362d4f 100644 --- a/window_scene/session/screen/include/screen_session.h +++ b/window_scene/session/screen/include/screen_session.h @@ -461,6 +461,7 @@ private: sptr defaultScreenSession); std::map, Point>> screenSessionMap_; + mutable std::shared_mutex screenSessionMapMutex_; }; } // namespace OHOS::Rosen diff --git a/window_scene/session/screen/src/screen_session.cpp b/window_scene/session/screen/src/screen_session.cpp index c3e0e83c056be135d2aa57ccb96d094d11f4ba3a..2a3bb38918ef49e7f59ab87d3dbf27627baf7961 100644 --- a/window_scene/session/screen/src/screen_session.cpp +++ b/window_scene/session/screen/src/screen_session.cpp @@ -1876,6 +1876,7 @@ ScreenSessionGroup::ScreenSessionGroup(ScreenId screenId, ScreenId rsId, ScreenSessionGroup::~ScreenSessionGroup() { ReleaseDisplayNode(); + std::unique_lock lock(screenSessionMapMutex_); screenSessionMap_.clear(); } @@ -1929,10 +1930,13 @@ bool ScreenSessionGroup::AddChild(sptr& smsScreen, Point& startPo return false; } ScreenId screenId = smsScreen->screenId_; - auto iter = screenSessionMap_.find(screenId); - if (iter != screenSessionMap_.end()) { - TLOGE(WmsLogTag::DMS, "AddChild, screenSessionMap_ has smsScreen:%{public}" PRIu64"", screenId); - return false; + { + std::shared_lock lock(screenSessionMapMutex_); + auto iter = screenSessionMap_.find(screenId); + if (iter != screenSessionMap_.end()) { + TLOGE(WmsLogTag::DMS, "AddChild, screenSessionMap_ has smsScreen:%{public}" PRIu64"", screenId); + return false; + } } struct RSDisplayNodeConfig config; if (!GetRSDisplayNodeConfig(smsScreen, config, defaultScreenSession)) { @@ -1941,7 +1945,10 @@ bool ScreenSessionGroup::AddChild(sptr& smsScreen, Point& startPo smsScreen->InitRSDisplayNode(config, startPoint, isExtend); smsScreen->lastGroupSmsId_ = smsScreen->groupSmsId_; smsScreen->groupSmsId_ = screenId_; - screenSessionMap_.insert(std::make_pair(screenId, std::make_pair(smsScreen, startPoint))); + { + std::unique_lock lock(screenSessionMapMutex_); + screenSessionMap_.insert(std::make_pair(screenId, std::make_pair(smsScreen, startPoint))); + } return true; } @@ -1977,16 +1984,19 @@ bool ScreenSessionGroup::RemoveChild(sptr& smsScreen) displayNode = nullptr; // attention: make sure reference count 0 RSTransactionAdapter::FlushImplicitTransaction(smsScreen->GetRSUIContext()); + std::unique_lock lock(screenSessionMapMutex_); return screenSessionMap_.erase(screenId); } bool ScreenSessionGroup::HasChild(ScreenId childScreen) const { + std::shared_lock lock(screenSessionMapMutex_); return screenSessionMap_.find(childScreen) != screenSessionMap_.end(); } std::vector> ScreenSessionGroup::GetChildren() const { + std::shared_lock lock(screenSessionMapMutex_); std::vector> res; for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) { res.push_back(iter->second.first); @@ -1996,6 +2006,7 @@ std::vector> ScreenSessionGroup::GetChildren() const std::vector ScreenSessionGroup::GetChildrenPosition() const { + std::shared_lock lock(screenSessionMapMutex_); std::vector res; for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) { res.push_back(iter->second.second); @@ -2005,6 +2016,7 @@ std::vector ScreenSessionGroup::GetChildrenPosition() const Point ScreenSessionGroup::GetChildPosition(ScreenId screenId) const { + std::shared_lock lock(screenSessionMapMutex_); Point point{}; auto iter = screenSessionMap_.find(screenId); if (iter != screenSessionMap_.end()) { @@ -2015,6 +2027,7 @@ Point ScreenSessionGroup::GetChildPosition(ScreenId screenId) const size_t ScreenSessionGroup::GetChildCount() const { + std::shared_lock lock(screenSessionMapMutex_); return screenSessionMap_.size(); } @@ -2031,8 +2044,11 @@ sptr ScreenSessionGroup::ConvertToScreenGroupInfo() const } FillScreenInfo(screenGroupInfo); screenGroupInfo->combination_ = combination_; - for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) { - screenGroupInfo->children_.push_back(iter->first); + { + std::shared_lock lock(screenSessionMapMutex_); + for (auto iter = screenSessionMap_.begin(); iter != screenSessionMap_.end(); iter++) { + screenGroupInfo->children_.push_back(iter->first); + } } auto positions = GetChildrenPosition(); screenGroupInfo->position_.insert(screenGroupInfo->position_.end(), positions.begin(), positions.end()); diff --git a/window_scene/test/dms_unittest/screen_session_manager_test.cpp b/window_scene/test/dms_unittest/screen_session_manager_test.cpp index cc6e7e6da9c79048342e8e8c357a4b1cb0655cb0..e43b2399d3297e60c293b0d7ed85c8aa5c10ca3e 100644 --- a/window_scene/test/dms_unittest/screen_session_manager_test.cpp +++ b/window_scene/test/dms_unittest/screen_session_manager_test.cpp @@ -6706,7 +6706,6 @@ HWTEST_F(ScreenSessionManagerTest, OnRemoteDied03, TestSize.Level1) ssm_->screenAgentMap_[agent] = {}; EXPECT_TRUE(ssm_->OnRemoteDied(agent)); - EXPECT_TRUE(ssm_->screenAgentMap_.find(agent) == ssm_->screenAgentMap_.end()); } /** 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 de0d8eb3171d988dce23a48debec12d3f78abb54..2f830aec0864d2054cd93243bbd1e5de72decee0 100644 --- a/window_scene/test/dms_unittest/screen_session_manager_test2.cpp +++ b/window_scene/test/dms_unittest/screen_session_manager_test2.cpp @@ -1128,6 +1128,20 @@ HWTEST_F(ScreenSessionManagerTest, NotifyScreenMaskAppear02, TestSize.Level1) g_errLog.find("screen mask appeared") != std::string::npos; EXPECT_TRUE(hasLog); } + +/** + * @tc.name: TryToCancelScreenOff01 + * @tc.desc: TryToCancelScreenOff test + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionManagerTest, TryToCancelScreenOff01, TestSize.Level1) +{ + g_errLog.clear(); + MockAccesstokenKit::MockIsSACalling(false); + MockAccesstokenKit::MockIsSystemApp(false); + ssm_->TryToCancelScreenOff(); + EXPECT_TRUE(g_errLog.find("permission denied!") != std::string::npos); +} } } } \ No newline at end of file