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 acd80dc31c..ec01a71898 100644 --- a/window_scene/screen_session_manager/include/screen_session_manager.h +++ b/window_scene/screen_session_manager/include/screen_session_manager.h @@ -977,7 +977,116 @@ private: bool needReinstallExemptionList_ = true; std::unordered_map hasPrivateWindowForeground_; std::atomic isRecoveringDisplayMode_ = { false }; + void UpdateLastDisplayInfo(DisplayId displayId, sptr displayInfo); + struct UnfreezeNotifyContext { + sptr displayInfo; + sptr screenInfo; + DMRect availableArea {}; + std::vector lastFoldAngles; + ScreenChangeEvent lastScreenChangeEvent = ScreenChangeEvent::UNKNOWN; + sptr lastDisplayChangeInfo; + ScreenSessionManager* mgr; + }; + class UnfreezeTask { + public: + explicit UnfreezeTask(sptr ag) : agent(ag) {} + virtual ~UnfreezeTask() = default; + virtual void Execute() = 0; + protected: + sptr agent; + }; + + class DisplayEventTask : public UnfreezeTask { + public: + DisplayEventTask(sptr ag, sptr info) + : UnfreezeTask(ag), displayInfo(info) {} + void Execute() override; + private: + sptr displayInfo; + }; + + class DisplayModeTask : public UnfreezeTask { + public: + DisplayModeTask(sptr ag, FoldDisplayMode mode) + : UnfreezeTask(ag), displayMode(mode) {} + void Execute() override; + private: + FoldDisplayMode displayMode; + }; + + class FoldStatusTask : public UnfreezeTask { + public: + FoldStatusTask(sptr ag, FoldStatus st) + : UnfreezeTask(ag), status(st) {} + void Execute() override; + private: + FoldStatus status; + }; + + class FoldAngleTask : public UnfreezeTask { + public: + FoldAngleTask(sptr ag, const std::vector& angles) + : UnfreezeTask(ag), foldAngles(angles) {} + void Execute() override; + private: + std::vector foldAngles; + }; + + class ScreenEventTask : public UnfreezeTask { + public: + ScreenEventTask(sptr ag, sptr info, ScreenChangeEvent evt) + : UnfreezeTask(ag), screenInfo(info), event(evt) {} + void Execute() override; + private: + sptr screenInfo; + ScreenChangeEvent event; + }; + + class DisplayUpdateTask : public UnfreezeTask { + public: + DisplayUpdateTask(sptr ag, sptr info) + : UnfreezeTask(ag), displayChangeInfo(info) {} + void Execute() override; + private: + sptr displayChangeInfo; + }; + + class AvailableAreaTask : public UnfreezeTask { + public: + AvailableAreaTask(sptr ag, DMRect rect, DisplayId id) + : UnfreezeTask(ag), area(rect), displayId(id) {} + void Execute() override; + private: + DMRect area; + DisplayId displayId; + }; + + class AttributeTask : public UnfreezeTask { + public: + AttributeTask(sptr ag, sptr info, + const std::vector& attrs, DisplayId id, ScreenSessionManager* mgr) + : UnfreezeTask(ag), displayInfo(info), attributes(attrs), displayId(id), manager(mgr) {} + void Execute() override; + private: + sptr displayInfo; + std::vector attributes; + DisplayId displayId; + ScreenSessionManager* manager; + }; + void CollectUnfreezedAttributeTasks(int32_t pid, DisplayManagerAgentType agentType, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::set& pidAgentTypes); + void CollectUnfreezedAgentTasks(int32_t pid, DisplayManagerAgentType agentType, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::set& pidAgentTypes); + void CollectUnfreezedTasks(const std::set& unfreezedPidList, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::vector>>& logData, + std::map>& pidAgentTypeMap); + std::vector> BuildUnfreezedTasks( + const std::set& unfreezedPidList, const UnfreezeNotifyContext& ctx, + std::map>& pidAgentTypeMap); class ScreenIdManager { friend class ScreenSessionGroup; public: 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 c6242ae811..6efb70ac28 100644 --- a/window_scene/screen_session_manager/src/screen_session_manager.cpp +++ b/window_scene/screen_session_manager/src/screen_session_manager.cpp @@ -14255,112 +14255,180 @@ DMError ScreenSessionManager::ProxyForFreeze(const std::set& pidList, b return DMError::DM_OK; } -void ScreenSessionManager::NotifyUnfreezedAttributeAgents(const int32_t& pid, const std::set& unfreezedPidList, - const sptr& screenSession) +void ScreenSessionManager::DisplayEventTask::Execute() { agent->OnDisplayChange(displayInfo, DisplayChangeEvent::DISPLAY_UNFREEZED); } +void ScreenSessionManager::DisplayModeTask::Execute() { agent->NotifyDisplayModeChanged(displayMode); } +void ScreenSessionManager::FoldStatusTask::Execute() { agent->NotifyFoldStatusChanged(status); } +void ScreenSessionManager::FoldAngleTask::Execute() { agent->NotifyFoldAngleChanged(foldAngles); } +void ScreenSessionManager::ScreenEventTask::Execute() { agent->OnScreenChange(screenInfo, event); } +void ScreenSessionManager::DisplayUpdateTask::Execute() { agent->NotifyDisplayChangeInfoChanged(displayChangeInfo); } +void ScreenSessionManager::AvailableAreaTask::Execute() { agent->NotifyAvailableAreaChanged(area, displayId); } +void ScreenSessionManager::AttributeTask::Execute() { - auto attributeAgentsMap = ScreenSessionManagerAdapter::GetInstance().dmAttributeAgentContainer_.GetAttributeAgentsMap(); + agent->OnDisplayAttributeChange(displayInfo, attributes); + manager->UpdateLastDisplayInfo(displayId, displayInfo); +} + + +void ScreenSessionManager::CollectUnfreezedAttributeTasks(int32_t pid, DisplayManagerAgentType agentType, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::set& pidAgentTypes) +{ + auto displayInfo = ctx.displayInfo; + if (displayInfo == nullptr) { + TLOGNFE(WmsLogTag::DMS, "DisplayInfo is nullptr"); + return; + } + DisplayId displayId = displayInfo->GetDisplayId(); + sptr lastDisplayInfo = new DisplayInfo(); + if (lastDisplayInfo == nullptr) { + TLOGNFE(WmsLogTag::DMS, "LastDisplayInfo of displayId: %{public}" PRIu64 "is nullptr", displayId); + return; + } + std::vector attributes; + ctx.mgr->GetChangedListenableAttribute(lastDisplayInfo, displayInfo, attributes); + if (attributes.empty()) { + TLOGNFW(WmsLogTag::DMS, "No attribute changed"); + return; + } + auto attributeAgentsMap = + ScreenSessionManagerAdapter::GetInstance().dmAttributeAgentContainer_.GetAttributeAgentsMap(); + bool hasTask = false; for (auto& it : attributeAgentsMap) { auto agent = it.second.first; - int32_t agentPid = ScreenSessionManagerAdapter::GetInstance().dmAttributeAgentContainer_.GetAgentPid(agent); - if (agent == nullptr|| agentPid != pid || unfreezedPidList.count(pid) == 0) { + int32_t agentPid = + ScreenSessionManagerAdapter::GetInstance().dmAttributeAgentContainer_.GetAgentPid(agent); + if (agent == nullptr || agentPid != pid) { continue; } - auto displayInfo = screenSession->ConvertToDisplayInfo(); - if (displayInfo == nullptr) { - TLOGNFE(WmsLogTag::DMS, "DisplayInfo is nullptr"); - continue; - } - std::vector attributes; - DisplayId displayId = displayInfo->GetDisplayId(); - sptr lastDisplayInfo = new DisplayInfo(); - if (lastDisplayInfo == nullptr) { - TLOGNFE(WmsLogTag::DMS, "LastDisplayInfo of displayId: %{public}" PRIu64 "is nullptr", displayId); - continue; - } - GetChangedListenableAttribute(lastDisplayInfo, displayInfo, attributes); - if (attributes.empty()) { - TLOGNFW(WmsLogTag::DMS, "No attribute changed"); - continue; - } - agent->OnDisplayAttributeChange(displayInfo, attributes); - pidAgentTypeMap_[pid].erase(DisplayManagerAgentType::DISPLAY_ATTRIBUTE_CHANGED_LISTENER); - std::lock_guard lock(lastDisplayInfoMapMutex_); + tasks.push_back(std::make_unique(agent, displayInfo, attributes, displayId, ctx.mgr)); + hasTask = true; + } + if (hasTask) { + pidAgentTypes.erase(agentType); } } -void ScreenSessionManager::NotifyUnfreezedAgents(const int32_t& pid, const std::set& unfreezedPidList, - const std::set& pidAgentTypes, const sptr& screenSession) +void ScreenSessionManager::CollectUnfreezedAgentTasks(int32_t pid, DisplayManagerAgentType agentType, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::set& pidAgentTypes) { - bool isAgentTypeNotify = false; - for (auto agentType : pidAgentTypes) { - if (agentType == DisplayManagerAgentType::DISPLAY_ATTRIBUTE_CHANGED_LISTENER) { - NotifyUnfreezedAttributeAgents(pid, unfreezedPidList, screenSession); + auto agents = ScreenSessionManagerAdapter::GetInstance().dmAgentContainer_.GetAgentsByType(agentType); + bool hasTask = false; + for (auto agent : agents) { + int32_t agentPid = ScreenSessionManagerAdapter::GetInstance().dmAgentContainer_.GetAgentPid(agent); + if (agent == nullptr || agentPid != pid) { continue; } - auto agents = ScreenSessionManagerAdapter::GetInstance().dmAgentContainer_.GetAgentsByType(agentType); - for (auto agent : agents) { - int32_t agentPid = ScreenSessionManagerAdapter::GetInstance().dmAgentContainer_.GetAgentPid(agent); - if (agent == nullptr|| agentPid != pid || unfreezedPidList.count(pid) == 0) { - continue; - } - isAgentTypeNotify = true; - if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) { - agent->OnDisplayChange(screenSession->ConvertToDisplayInfo(), DisplayChangeEvent::DISPLAY_UNFREEZED); - } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) { - FoldDisplayMode displayMode = GetFoldDisplayMode(); - agent->NotifyDisplayModeChanged(displayMode); - } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) { - FoldStatus foldStatus = GetFoldStatus(); - agent->NotifyFoldStatusChanged(foldStatus); - } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) { - std::lock_guard lock(lastStatusUpdateMutex_); - agent->NotifyFoldAngleChanged(lastFoldAngles_); - } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) { - auto displayInfo = screenSession->ConvertToDisplayInfo(); - auto screenInfo = GetScreenInfoById(displayInfo->GetScreenId()); - std::lock_guard lock(lastStatusUpdateMutex_); - agent->OnScreenChange(screenInfo, lastScreenChangeEvent_); - } else if (agentType == DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) { - std::lock_guard lock(lastStatusUpdateMutex_); - agent->NotifyDisplayChangeInfoChanged(lastDisplayChangeInfo_); - } else if (agentType == DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) { - auto area = screenSession->GetAvailableArea(); - auto displayId = screenSession->ConvertToDisplayInfo()->GetDisplayId(); - std::lock_guard lock(lastStatusUpdateMutex_); - agent->NotifyAvailableAreaChanged(area, displayId); + hasTask = true; + if (agentType == DisplayManagerAgentType::DISPLAY_EVENT_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.displayInfo)); + } else if (agentType == DisplayManagerAgentType::DISPLAY_MODE_CHANGED_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.mgr->GetFoldDisplayMode())); + } else if (agentType == DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.mgr->GetFoldStatus())); + } else if (agentType == DisplayManagerAgentType::FOLD_ANGLE_CHANGED_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.lastFoldAngles)); + } else if (agentType == DisplayManagerAgentType::SCREEN_EVENT_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.screenInfo, ctx.lastScreenChangeEvent)); + } else if (agentType == DisplayManagerAgentType::DISPLAY_UPDATE_LISTENER) { + tasks.push_back(std::make_unique(agent, ctx.lastDisplayChangeInfo)); + } else if (agentType == DisplayManagerAgentType::AVAILABLE_AREA_CHANGED_LISTENER) { + DisplayId displayId = ctx.displayInfo == nullptr ? DISPLAY_ID_INVALID : ctx.displayInfo->GetDisplayId(); + tasks.push_back(std::make_unique(agent, ctx.availableArea, displayId)); + } else { + hasTask = false; + TLOGNFI(WmsLogTag::DMS, "Unknown agentType."); + } + } + if (hasTask) { + pidAgentTypes.erase(agentType); + } +} + +void ScreenSessionManager::CollectUnfreezedTasks(const std::set& unfreezedPidList, + const UnfreezeNotifyContext& ctx, std::vector>& tasks, + std::vector>>& logData, + std::map>& pidAgentTypeMap) +{ + std::lock_guard lock(ctx.mgr->freezedPidListMutex_); + for (auto iter = pidAgentTypeMap.begin(); iter != pidAgentTypeMap.end();) { + int32_t pid = iter->first; + if (unfreezedPidList.count(pid) == 0) { + ++iter; + continue; + } + auto& pidAgentTypes = iter->second; + logData.push_back({pid, pidAgentTypes}); + + auto agentTypesCopy = pidAgentTypes; + for (auto agentType : agentTypesCopy) { + if (agentType == DisplayManagerAgentType::DISPLAY_ATTRIBUTE_CHANGED_LISTENER) { + CollectUnfreezedAttributeTasks(pid, agentType, ctx, tasks, pidAgentTypes); } else { - isAgentTypeNotify = false; - TLOGNFI(WmsLogTag::DMS, "Unknown agentType."); + CollectUnfreezedAgentTasks(pid, agentType, ctx, tasks, pidAgentTypes); } } - if (isAgentTypeNotify) { - pidAgentTypeMap_[pid].erase(agentType); + if (pidAgentTypes.empty()) { + iter = pidAgentTypeMap.erase(iter); + } else { + ++iter; } } } +void LogUnfreezedInfo(const std::vector>>& logData) +{ + std::string result = "pid,type:"; + for (auto& entry : logData) { + result.append(std::to_string(entry.first)).append(","); + for (auto type : entry.second) { + result.append(std::to_string(static_cast(type))).append(" "); + } + result.append("|"); + } + TLOGNFW(WmsLogTag::DMS, "%{public}s", result.c_str()); +} + +std::vector> ScreenSessionManager::BuildUnfreezedTasks( + const std::set& unfreezedPidList, + const UnfreezeNotifyContext& ctx, + std::map>& pidAgentTypeMap) +{ + std::vector> tasks; + std::vector>> logData; + CollectUnfreezedTasks(unfreezedPidList, ctx, tasks, logData, pidAgentTypeMap); + LogUnfreezedInfo(logData); + return tasks; +} + + void ScreenSessionManager::NotifyUnfreezed(const std::set& unfreezedPidList, const sptr& screenSession) { - std::lock_guard lock(freezedPidListMutex_); - std::ostringstream oss; - oss << "pid,type:"; - for (auto iter = pidAgentTypeMap_.begin(); iter != pidAgentTypeMap_.end();) { - int32_t pid = iter->first; - auto pidAgentTypes = iter->second; - NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession); - if (pidAgentTypeMap_[pid].empty()) { - iter = pidAgentTypeMap_.erase(iter); - } else { - iter++; - } - oss << pid << ","; - for (auto type : pidAgentTypes) { - oss << static_cast(type) << " "; - } - oss << "|"; + UnfreezeNotifyContext ctx; + ctx.mgr = this; + ctx.displayInfo = screenSession->ConvertToDisplayInfo(); + if (ctx.displayInfo != nullptr) { + ctx.screenInfo = GetScreenInfoById(ctx.displayInfo->GetScreenId()); + ctx.availableArea = screenSession->GetAvailableArea(); } - TLOGNFW(WmsLogTag::DMS, "%{public}s", oss.str().c_str()); + { + std::lock_guard lock(lastStatusUpdateMutex_); + ctx.lastFoldAngles = lastFoldAngles_; + ctx.lastScreenChangeEvent = lastScreenChangeEvent_; + ctx.lastDisplayChangeInfo = lastDisplayChangeInfo_; + } + + auto tasks = BuildUnfreezedTasks(unfreezedPidList, ctx, pidAgentTypeMap_); + for (auto& task : tasks) { + task->Execute(); + } +} + +void ScreenSessionManager::UpdateLastDisplayInfo(DisplayId displayId, sptr displayInfo) +{ + std::lock_guard lock(lastDisplayInfoMapMutex_); + lastDisplayInfoMap_[displayId] = displayInfo; } DMError ScreenSessionManager::ResetAllFreezeStatus() diff --git a/window_scene/test/dms_unittest/screen_session_manager_test_seven.cpp b/window_scene/test/dms_unittest/screen_session_manager_test_seven.cpp index f8df01fbd2..fdad4174f3 100644 --- a/window_scene/test/dms_unittest/screen_session_manager_test_seven.cpp +++ b/window_scene/test/dms_unittest/screen_session_manager_test_seven.cpp @@ -790,10 +790,7 @@ HWTEST_F(ScreenSessionManagerTest, ProxyForFreeze, TestSize.Level1) std::set pidAgentTypes = {DisplayManagerAgentType::SCREEN_EVENT_LISTENER}; ScreenId screenId = 1050; sptr screenSession = new (std::nothrow) ScreenSession(screenId, ScreenProperty(), 0); - ssm_->NotifyUnfreezedAgents(pid, unfreezedPidList, pidAgentTypes, screenSession); - ssm_->NotifyUnfreezed(unfreezedPidList, screenSession); - std::set pidList = {1, 2, 3}; DMError ret = ssm_->ProxyForFreeze(pidList, true); ASSERT_EQ(ret, DMError::DM_OK);