diff --git a/dmserver/include/abstract_display.h b/dmserver/include/abstract_display.h index d05d067d141b4422675a5d5c7261c52072b64a67..8d8084c1f580a8bb1b596cc3587c3f3c06b9258f 100644 --- a/dmserver/include/abstract_display.h +++ b/dmserver/include/abstract_display.h @@ -58,6 +58,7 @@ public: void SetOffsetY(int32_t offsetY); void SetWidth(int32_t width); void SetHeight(int32_t height); + void SetOffset(int32_t offsetX, int32_t offsetY); void SetRefreshRate(uint32_t refreshRate); void SetVirtualPixelRatio(float virtualPixelRatio); void SetOrientation(Orientation orientation); diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h index dc89641e5e2c88359e6bbc6038bb6968ffba58e4..f2b28a287496625125e10dce9a1c39e61e697ece 100644 --- a/dmserver/include/abstract_screen.h +++ b/dmserver/include/abstract_screen.h @@ -92,6 +92,7 @@ public: bool HasChild(ScreenId childScreen) const; std::vector> GetChildren() const; std::vector GetChildrenPosition() const; + Point GetChildPosition(ScreenId screenId) const; size_t GetChildCount() const; sptr ConvertToScreenGroupInfo() const; diff --git a/dmserver/src/abstract_display.cpp b/dmserver/src/abstract_display.cpp index c5d42306cd974a3a7ba935acc5e21aa96113c461..ecdb19292decc7291c385ce82e550dc5d7ea76c5 100644 --- a/dmserver/src/abstract_display.cpp +++ b/dmserver/src/abstract_display.cpp @@ -104,6 +104,12 @@ void AbstractDisplay::SetHeight(int32_t height) height_ = height; } +void AbstractDisplay::SetOffset(int32_t offsetX, int32_t offsetY) +{ + offsetX_ = offsetX; + offsetY_ = offsetY; +} + void AbstractDisplay::SetRefreshRate(uint32_t refreshRate) { refreshRate_ = refreshRate; @@ -166,11 +172,15 @@ bool AbstractDisplay::BindAbstractScreen(sptr abstractScreen) id_, dmsScreenId); return false; } + + Point point = abstractScreen->GetGroup()->GetChildPosition(dmsScreenId); + offsetX_ = point.posX_; + offsetY_ = point.posY_; width_ = static_cast(info->width_); height_ = static_cast(info->height_); refreshRate_ = info->refreshRate_; screenId_ = dmsScreenId; - WLOGD("display bound to screen. display:%{public}" PRIu64", screen:%{public}" PRIu64"", id_, dmsScreenId); + WLOGD("display bind to screen. display:%{public}" PRIu64", screen:%{public}" PRIu64"", id_, dmsScreenId); return true; } diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index a7c0d4af5c5c8ea55a85623b5f12ac97c5d2b806..df9e823c37759f67070598507044b0f5e1a61d2e 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -224,16 +224,20 @@ DisplayId AbstractDisplayController::ProcessExpandScreenDisconnected( WLOGFE("Invalid params as nullptr."); return DISPLAY_ID_INVALID; } + DisplayId displayId = DISPLAY_ID_INVALID; for (auto iter = abstractDisplayMap_.begin(); iter != abstractDisplayMap_.end(); iter++) { - DisplayId displayId = iter->first; sptr abstractDisplay = iter->second; if (abstractDisplay->GetAbstractScreenId() == absScreen->dmsId_) { WLOGI("expand screen disconnect, displayId: %{public}" PRIu64", screenId: %{public}" PRIu64"", displayId, abstractDisplay->GetAbstractScreenId()); - return displayId; + displayId = iter->first; + } else { + abstractDisplay->SetOffset(0, 0); + auto screenId = abstractDisplay->GetAbstractScreenId(); + abstractScreenController_->GetRSDisplayNodeByScreenId(screenId)->SetDisplayOffset(0, 0); } } - return DISPLAY_ID_INVALID; + return displayId; } void AbstractDisplayController::OnAbstractScreenChange(sptr absScreen, DisplayChangeEvent event) @@ -461,8 +465,12 @@ void AbstractDisplayController::AddScreenToExpandLocked(sptr abs WLOGE("bind display error, cannot get info."); return; } + sptr display = new AbstractDisplay(displayCount_.fetch_add(1), absScreen->dmsId_, info->width_, info->height_, info->refreshRate_); + Point point = abstractScreenController_->GetAbstractScreenGroup(absScreen->groupDmsId_)-> + GetChildPosition(absScreen->dmsId_); + display->SetOffset(point.posX_, point.posY_); abstractDisplayMap_.insert((std::make_pair(display->GetId(), display))); WLOGI("create display for new screen. screen:%{public}" PRIu64", display:%{public}" PRIu64"", absScreen->dmsId_, display->GetId()); diff --git a/dmserver/src/abstract_screen.cpp b/dmserver/src/abstract_screen.cpp index 92ce791ec3a214361456ebd125f9f8cbb4850a39..2751b6f210c87ef33e30d25d479ecb6e48efb8de 100644 --- a/dmserver/src/abstract_screen.cpp +++ b/dmserver/src/abstract_screen.cpp @@ -379,12 +379,14 @@ bool AbstractScreenGroup::RemoveChild(sptr& dmsScreen) } ScreenId screenId = dmsScreen->dmsId_; dmsScreen->groupDmsId_ = SCREEN_ID_INVALID; - if (rsDisplayNode_ != nullptr) { - rsDisplayNode_->RemoveFromTree(); + if (dmsScreen->rsDisplayNode_ != nullptr) { + dmsScreen->rsDisplayNode_->SetDisplayOffset(0, 0); + dmsScreen->rsDisplayNode_->RemoveFromTree(); auto transactionProxy = RSTransactionProxy::GetInstance(); if (transactionProxy != nullptr) { transactionProxy->FlushImplicitTransaction(); } + dmsScreen->rsDisplayNode_ = nullptr; } return abstractScreenMap_.erase(screenId); } @@ -412,6 +414,16 @@ std::vector AbstractScreenGroup::GetChildrenPosition() const return res; } +Point AbstractScreenGroup::GetChildPosition(ScreenId screenId) const +{ + Point point; + auto iter = abstractScreenMap_.find(screenId); + if (iter != abstractScreenMap_.end()) { + point = iter->second.second; + } + return point; +} + size_t AbstractScreenGroup::GetChildCount() const { return abstractScreenMap_.size(); diff --git a/dmserver/src/abstract_screen_controller.cpp b/dmserver/src/abstract_screen_controller.cpp index 72daa8331d9a25d821de45c135c70f4c44cfdd02..f185f152f24ad91e0a10928fe7be5dcef94d1164 100644 --- a/dmserver/src/abstract_screen_controller.cpp +++ b/dmserver/src/abstract_screen_controller.cpp @@ -445,8 +445,8 @@ sptr AbstractScreenController::AddAsFirstScreenLocked(sptr< dmsScreenGroupMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup)); dmsScreenMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup)); screenGroup->mirrorScreenId_ = newScreen->dmsId_; - WLOGI("connect new group screen. id=%{public}" PRIu64"/%{public}" PRIu64", combination:%{public}u", - newScreen->dmsId_, dmsGroupScreenId, newScreen->type_); + WLOGI("connect new group screen, screenId: %{public}" PRIu64", screenGroupId: %{public}" PRIu64", " + "combination:%{public}u", newScreen->dmsId_, dmsGroupScreenId, newScreen->type_); return screenGroup; } @@ -468,6 +468,9 @@ sptr AbstractScreenController::AddAsSuccedentScreenLocked(s } auto screenGroup = screenGroupIter->second; Point point; + if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) { + point = {screen->GetActiveScreenMode()->width_, 0}; + } screenGroup->AddChild(newScreen, point); return screenGroup; } @@ -861,6 +864,7 @@ void AbstractScreenController::AddScreenToGroup(sptr group, abstractScreenCallback_->onConnect_(screen); } } + NotifyScreenGroupChanged(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP); NotifyScreenGroupChanged(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP); NotifyScreenGroupChanged(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP); diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 58b2ad163fd5f403884c6dc4ccb1a19d1e6092b0..36d17c237a9af47fada5fa2de4702a5323d49a4a 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -489,8 +489,8 @@ ScreenId DisplayManagerService::MakeExpand(std::vector expandScreenIds return SCREEN_ID_INVALID; } std::shared_ptr rsDisplayNode; - for (uint32_t i = 0; i < expandScreenIds.size(); i++) { - rsDisplayNode = abstractScreenController_->GetRSDisplayNodeByScreenId(expandScreenIds[i]); + for (uint32_t i = 0; i < allExpandScreenIds.size(); i++) { + rsDisplayNode = abstractScreenController_->GetRSDisplayNodeByScreenId(allExpandScreenIds[i]); if (rsDisplayNode != nullptr) { rsDisplayNode->SetDisplayOffset(startPoints[i].posX_, startPoints[i].posY_); } diff --git a/interfaces/innerkits/dm/dm_common.h b/interfaces/innerkits/dm/dm_common.h index 90535e648febe342f13ae8f903270891625d2f27..212334dc46c464e66d7606f020427ef86c11bce8 100644 --- a/interfaces/innerkits/dm/dm_common.h +++ b/interfaces/innerkits/dm/dm_common.h @@ -30,7 +30,7 @@ namespace { const static std::string DEFAULT_SCREEN_NAME = "buildIn"; constexpr int DOT_PER_INCH_MAXIMUM_VALUE = 640; constexpr int DOT_PER_INCH_MINIMUM_VALUE = 80; - constexpr uint32_t BASELINE_DENSITY = 160; // + constexpr uint32_t BASELINE_DENSITY = 160; } enum class PowerStateChangeReason : uint32_t { diff --git a/snapshot/snapshot_virtual_screen.cpp b/snapshot/snapshot_virtual_screen.cpp index 537c4893b1805ddd6a983d10cf497c523927579c..745ec27412409ae63aeb7ffd0465c3c40bcfffa0 100644 --- a/snapshot/snapshot_virtual_screen.cpp +++ b/snapshot/snapshot_virtual_screen.cpp @@ -94,4 +94,4 @@ int main(int argc, char *argv[]) ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId); std::cout << "DestroyVirtualScreen " << virtualScreenId << std::endl; return 0; -} \ No newline at end of file +} diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 6ee024b6e42d951e4243789904bd1d8fe9b2f167..37a4db44ac47c16a3fb1a872f7d33facd610c209 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -69,6 +69,7 @@ ohos_shared_library("libwms") { "../wm/src/zidl/window_manager_agent_proxy.cpp", "../wm/src/zidl/window_proxy.cpp", "src/avoid_area_controller.cpp", + "src/display_group_controller.cpp", "src/drag_controller.cpp", "src/freeze_controller.cpp", "src/input_window_monitor.cpp", diff --git a/wmserver/include/display_group_controller.h b/wmserver/include/display_group_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..83a4b622c7ce50535085fe10deae4e6e5304ff95 --- /dev/null +++ b/wmserver/include/display_group_controller.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 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_DISPLAY_GROUP_CONTROLLER_H +#define OHOS_ROSEN_DISPLAY_GROUP_CONTROLLER_H + +#include + +#include "avoid_area_controller.h" +#include "display_info.h" +#include "display_manager_service_inner.h" +#include "window_layout_policy.h" +#include "window_manager.h" +#include "window_node.h" +#include "window_pair.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +using SysBarNodeMap = std::unordered_map>; +using SysBarTintMap = std::unordered_map; +class WindowNodeContainer; + +class DisplayGroupController : public RefBase { +public: + DisplayGroupController(const sptr& windowNodeContainer, + std::map& displayRectMap, std::map>& displayInfosMap) + : windowNodeContainer_(windowNodeContainer), displayRectMap_(displayRectMap), + displayInfosMap_(displayInfosMap) {} + ~DisplayGroupController() = default; + + void InitNewDisplay(DisplayId displayId); + void UpdateWindowNodeMaps(); + void PreProcessWindowNode(const sptr& node, WindowUpdateType type); + void ProcessDisplayCreate(DisplayId displayId, + const std::map>& displayInfoMap); + void ProcessDisplayDestroy(DisplayId displayId, + const std::map>& displayInfoMap, + std::vector& windowIds); + void ProcessDisplayChange(DisplayId displayId, + const std::map>& displayInfoMap, + DisplayStateChangeType type); + sptr GetWindowPairByDisplayId(DisplayId displayId); + + WindowNodeMaps windowNodeMaps_; + std::map sysBarNodeMaps_; + std::map sysBarTintMaps_; + +private: + std::vector>* GetWindowNodesByDisplayIdAndRootType(DisplayId displayId, WindowRootNodeType type); + void AddWindowNodeOnWindowTree(sptr& node, WindowRootNodeType rootType); + void ProcessNotCrossNodesOnDestroiedDisplay(DisplayId displayId, std::vector& windowIds); + void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, + const std::map>& displayInfoMap, DisplayStateChangeType type); + void ProcessCrossNodes(DisplayStateChangeType type); + void MoveCrossNodeToTargetDisplay(const sptr& node, DisplayId targetDisplayId); + void MoveNotCrossNodeToDefaultDisplay(const sptr& node, DisplayId displayId); + void UpdateWindowShowingDisplays(const sptr& node, const Rect& requestRect); + void UpdateWindowDisplayIdIfNeeded(const sptr& node, + const std::vector& curShowingDisplays); + void UpdateWindowDisplayId(const sptr& node, DisplayId newDisplayId); + void ClearMapOfDestroiedDisplay(DisplayId displayId); + void CalculateNodeAbsoluteCordinate(const sptr& node); + + sptr windowNodeContainer_; + std::map& displayRectMap_; + std::map>& displayInfosMap_; + std::map> windowPairMap_; + DisplayId defaultDisplayId_; +}; +} // namespace Rosen +} // namespace OHOS +#endif // OHOS_ROSEN_DISPLAY_GROUP_CONTROLLER_H diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index 0086215be04d38c0a7c964bd51079e282561cea0..5184a9935e6595d58f1433cb866f4b0ea4e8a923 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -39,7 +39,6 @@ public: virtual void Clean(); virtual void Reset(); virtual void Reorder(); - virtual void UpdateDisplayInfo(const std::map& displayRectMap); virtual void AddWindowNode(const sptr& node) = 0; virtual void LayoutWindowTree(DisplayId displayId); virtual void RemoveWindowNode(const sptr& node); @@ -47,6 +46,11 @@ public: virtual void UpdateLayoutRect(const sptr& node) = 0; float GetVirtualPixelRatio(DisplayId displayId) const; void UpdateClientRectAndResetReason(const sptr& node, const Rect& lastLayoutRect, const Rect& winRect); + Rect GetDisplayGroupRect() const; + bool IsMultiDisplay(); + void ProcessDisplayCreate(DisplayId displayId, const std::map& displayRectMap); + void ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap); + void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, const std::map& displayRectMap); protected: void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); @@ -54,12 +58,24 @@ protected: virtual void LayoutWindowNode(const sptr& node); AvoidPosType GetAvoidPosType(const Rect& rect, DisplayId displayId) const; void CalcAndSetNodeHotZone(Rect layoutOutRect, const sptr& node) const; - void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; + void LimitFloatingWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; + void LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const; void ComputeDecoratedRequestRect(const sptr& node) const; bool IsVerticalDisplay(DisplayId displayId) const; bool IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const; void LayoutWindowNodesByRootType(const std::vector>& nodeVec); void UpdateSurfaceBounds(const sptr& node, const Rect& winRect); + void UpdateNodesAbsoluteCordinatesInAllDisplay(DisplayId displayId, + const Rect& srcDisplayRect, + const Rect& dstDisplayRect); + void UpdateNodeAbsoluteCordinate(const sptr& node, + const Rect& srcDisplayRect, + const Rect& dstDisplayRect); + void LimitWindowToBottomRightCorner(const sptr& node); + void UpdateDisplayGroupRect(); + void UpdateDisplayGroupLimitRect_(); + void UpdateMultiDisplayFlag(); + void PostProcessWhenDisplayChange(); const std::set avoidTypes_ { WindowType::WINDOW_TYPE_STATUS_BAR, @@ -69,6 +85,9 @@ protected: mutable std::map limitRectMap_; WindowNodeMaps& windowNodeMaps_; std::map>& displayInfosMap_; + Rect displayGroupRect_; + Rect displayGroupLimitRect_; + bool isMultiDisplay_ = false; }; } } diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index c5741e06e74490761715d64172dfa0dd9572f887..e33a692d83ad91671b82787ac3e463fe8d246c75 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -68,6 +68,7 @@ public: uint32_t GetCallingWindow() const; void SetWindowSizeChangeReason(WindowSizeChangeReason reason); void SetRequestedOrientation(Orientation orientation); + void SetShowingDisplays(const std::vector& displayIdVec); const sptr& GetWindowToken() const; uint32_t GetWindowId() const; uint32_t GetParentId() const; @@ -92,6 +93,7 @@ public: bool IsSplitMode() const; WindowSizeChangeReason GetWindowSizeChangeReason() const; Orientation GetRequestedOrientation() const; + std::vector GetShowingDisplays() const; void ResetWindowSizeChangeReason(); sptr parent_; @@ -108,6 +110,9 @@ public: bool isPlayAnimationShow_ { false }; bool isPlayAnimationHide_ { false }; bool startingWindowShown_ { false }; + bool isShowingOnMultiDisplays_ { false }; + std::vector showingDisplays_; + private: sptr property_ = nullptr; sptr windowToken_ = nullptr; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index ecfaea22b82634d85d00e9765d89c5539a29e900..90f10110ab25e9e9dfcbb5f4a472314cc6e0ac02 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -20,6 +20,7 @@ #include "avoid_area_controller.h" #include "display_info.h" #include "minimize_app.h" +#include "display_group_controller.h" #include "window_layout_policy.h" #include "window_manager.h" #include "window_node.h" @@ -31,8 +32,6 @@ namespace OHOS { namespace Rosen { using WindowNodeOperationFunc = std::function)>; // return true indicates to stop traverse -using SysBarNodeMap = std::unordered_map>; -using SysBarTintMap = std::unordered_map; class WindowNodeContainer : public RefBase { public: WindowNodeContainer(const sptr& displayInfo); @@ -81,41 +80,36 @@ public: WMError SetWindowMode(sptr& node, WindowMode dstMode); WMError SwitchLayoutPolicy(WindowLayoutMode mode, DisplayId displayId, bool reorder = false); void RaiseSplitRelatedWindowToTop(sptr& node); - void MoveWindowNodes(DisplayId displayId, std::vector& windowIds); float GetVirtualPixelRatio(DisplayId displayId) const; + Rect GetDisplayGroupRect() const; void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const; void UpdateSizeChangeReason(sptr& node, WindowSizeChangeReason reason); void GetWindowList(std::vector>& windowList) const; void DropShowWhenLockedWindowIfNeeded(const sptr& node); - void ProcessDisplayCreate(const sptr& displayInfo); - void ProcessDisplayDestroy(DisplayId displayId, std::vector& windowIds); - void ProcessDisplayChange(DisplayId displayId, const Rect& displayRect); void SetMinimizedByOther(bool isMinimizedByOther); void GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config); - void UpdateVirtualPixelRatio(DisplayId displayId, float virtualPixelRatio); - void SetDisplaySize(DisplayId displayId, uint32_t width, uint32_t height); - void SetDisplayVirtualPixelRatio(DisplayId displayId, float virtualPixelRatio); - void SetDisplayRotation(DisplayId displayId, Rotation rotation); - void AddDisplay(const sptr& displayInfo); - void DeleteDisplay(const sptr& displayInfo); sptr GetDisplayInfo(DisplayId displayId); float GetDisplayVirtualPixelRatio(DisplayId displayId) const; + bool UpdateRSTree(sptr& node, DisplayId displayId, bool isAdd, bool animationPlayed = false); + + sptr GetLayoutPolicy() const; + sptr GetAvoidController() const; + sptr GetMutiDisplayController() const; + sptr GetRootNode(WindowRootNodeType type) const; private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; sptr FindRoot(WindowType type) const; - std::vector>* FindNodeVectorOfRoot(DisplayId displayId, WindowRootNodeType type); sptr FindWindowNodeById(uint32_t id) const; void UpdateFocusStatus(uint32_t id, bool focused) const; void UpdateActiveStatus(uint32_t id, bool isActive) const; - void UpdateWindowTree(sptr& node); - bool UpdateRSTree(sptr& node, bool isAdd, bool animationPlayed = false); void NotifyIfSystemBarTintChanged(DisplayId displayId); void NotifyIfSystemBarRegionChanged(DisplayId displayId); void TraverseAndUpdateWindowState(WindowState state, int32_t topPriority); + void UpdateWindowTree(sptr& node); void UpdateWindowState(sptr node, int32_t topPriority, WindowState state); void HandleKeepScreenOn(const sptr& node, WindowState state); bool IsTopWindow(uint32_t windowId, sptr& rootNode) const; @@ -138,41 +132,34 @@ private: void RaiseShowWhenLockedWindowIfNeeded(const sptr& node); void ReZOrderShowWhenLockedWindows(const sptr& node, bool up); - void InitSysBarMapForDisplay(DisplayId displayId); - void InitWindowNodeMapForDisplay(DisplayId displayId); WMError AddWindowNodeOnWindowTree(sptr& node, const sptr& parentNode); void RemoveWindowNodeFromWindowTree(sptr& node); - void AddWindowNodeInRootNodeVector(sptr& node, WindowRootNodeType rootType); - void RemoveWindowNodeFromRootNodeVector(sptr& node, WindowRootNodeType rootType); - void UpdateWindowNodeMaps(); + void UpdateRSTreeWhenShowingDisplaysChange(sptr& node, + const std::vector& lastShowingDisplays, + const std::vector& curShowingDisplays); -private: float displayBrightness_ = UNDEFINED_BRIGHTNESS; uint32_t brightnessWindow_ = INVALID_WINDOW_ID; uint32_t zOrder_ { 0 }; uint32_t focusedWindow_ { INVALID_WINDOW_ID }; uint32_t activeWindow_ = INVALID_WINDOW_ID; - sptr avoidController_; std::vector backupWindowIds_; sptr zorderPolicy_ = new WindowZorderPolicy(); std::unordered_map> layoutPolicys_; WindowLayoutMode layoutMode_ = WindowLayoutMode::CASCADE; - sptr layoutPolicy_; - std::vector currentCoveredArea_; - std::map sysBarNodeMaps_; - std::map sysBarTintMaps_; - - sptr windowPair_; std::vector removedIds_; + sptr belowAppWindowNode_ = new WindowNode(); sptr appWindowNode_ = new WindowNode(); sptr aboveAppWindowNode_ = new WindowNode(); + sptr layoutPolicy_; + sptr avoidController_; + sptr displayGroupController_; + std::map displayRectMap_; std::map> displayInfosMap_; - - WindowNodeMaps windowNodeMaps_; }; } // namespace Rosen } // namespace OHOS diff --git a/wmserver/include/window_pair.h b/wmserver/include/window_pair.h index b7f85ee7a979b1f5e5c35a19bcda233936d92666..19ce011ff779b6d131b3416b122e4348e7d4503a 100644 --- a/wmserver/include/window_pair.h +++ b/wmserver/include/window_pair.h @@ -19,6 +19,7 @@ #include #include "window_inner_manager.h" #include "window_node.h" +#include "window_layout_policy.h" #include "wm_common_inner.h" #include "wm_common.h" @@ -53,7 +54,7 @@ public: * @param displayId the disply of window pair * @param appNode the window root of app window */ - WindowPair(const DisplayId& displayId, sptr& appNode); + WindowPair(const DisplayId& displayId, WindowNodeMaps& windowNodeMaps); /** * Deconstructor used to deconstruct. @@ -231,6 +232,7 @@ private: sptr secondary_; sptr divider_; WindowPairStatus status_ = {WindowPairStatus::STATUS_EMPTY}; + WindowNodeMaps& windowNodeMaps_; }; } // namespace Rosen } // namespace OHOS diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index ee16b0d5b22ff71e8ffbed685a1b6dbfb859ae95..6edd3735ea9bfa2ca173c918532a6cf6835b45d6 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -62,7 +62,7 @@ public: WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); void ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason); - void ProcessDisplayChange(const sptr& displayInfo, DisplayStateChangeType type); + void ProcessDisplayChange(DisplayId displayId, DisplayStateChangeType type); void ProcessDisplayDestroy(DisplayId displayId); void ProcessDisplayCreate(DisplayId displayId); @@ -70,6 +70,7 @@ public: WMError RaiseZOrderForAppWindow(sptr& node); void FocusFaultDetection() const; float GetVirtualPixelRatio(DisplayId displayId) const; + Rect GetDisplayGroupRect(DisplayId displayId) const; WMError UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason); void SetBrightness(uint32_t windowId, float brightness); void HandleKeepScreenOn(uint32_t windowId, bool requireLock); @@ -78,7 +79,6 @@ public: void SetMaxAppWindowNumber(int windowNum); WMError GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config); - void NotifyVirtualPixelRatioChange(sptr displayInfo); std::vector GetAllDisplayIds() const; void SetWindowStretchable(bool stretchable); @@ -96,6 +96,7 @@ private: const sptr& container, Rect rect); ScreenId GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay); void ProcessExpandDisplayCreate(DisplayId displayId, ScreenId screenGroupId); + std::map> GetAllDisplayInfos(const std::vector& displayIdVec); std::recursive_mutex& mutex_; std::map> windowNodeMap_; diff --git a/wmserver/src/display_group_controller.cpp b/wmserver/src/display_group_controller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdbe50f06cd014b8e1442c2d8684d0d708c79a3b --- /dev/null +++ b/wmserver/src/display_group_controller.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2022 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 "display_group_controller.h" + +#include "window_manager_hilog.h" +#include "window_node_container.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayGroupController"}; +} + +void DisplayGroupController::InitNewDisplay(DisplayId displayId) +{ + // system bar map for display + SysBarNodeMap sysBarNodeMap { + { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, + { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, + }; + sysBarNodeMaps_.insert(std::make_pair(displayId, sysBarNodeMap)); + + SysBarTintMap sysBarTintMap { + { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarRegionTint() }, + { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() }, + }; + sysBarTintMaps_.insert(std::make_pair(displayId, sysBarTintMap)); + + // window node maps for display + std::map>>> windowRootNodeMap; + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::APP_WINDOW_NODE, + std::make_unique>>())); + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::ABOVE_WINDOW_NODE, + std::make_unique>>())); + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::BELOW_WINDOW_NODE, + std::make_unique>>())); + windowNodeMaps_.insert(std::make_pair(displayId, std::move(windowRootNodeMap))); + + // window pair for display + auto windowPair = new WindowPair(displayId, windowNodeMaps_); + windowPairMap_.insert(std::make_pair(displayId, windowPair)); +} + +std::vector>* DisplayGroupController::GetWindowNodesByDisplayIdAndRootType(DisplayId displayId, + WindowRootNodeType type) +{ + if (windowNodeMaps_.find(displayId) != windowNodeMaps_.end()) { + auto& rootNodemap = windowNodeMaps_[displayId]; + if (rootNodemap.find(type) != rootNodemap.end()) { + return rootNodemap[type].get(); + } + } + return nullptr; +} + +void DisplayGroupController::AddWindowNodeOnWindowTree(sptr& node, WindowRootNodeType rootType) +{ + std::vector>* rootNodeVectorPtr = GetWindowNodesByDisplayIdAndRootType(node->GetDisplayId(), + rootType); + if (rootNodeVectorPtr != nullptr) { + rootNodeVectorPtr->push_back(node); + WLOGFI("add node in node vector of root, displayId: %{public}" PRIu64" windowId: %{public}d, " + "rootType: %{public}d", node->GetDisplayId(), node->GetWindowId(), rootType); + } else { + WLOGFE("add node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", + node->GetWindowId(), rootType); + } +} + +void DisplayGroupController::UpdateWindowNodeMaps() +{ + // clear ori windowNodeMaps + for (auto& elem : windowNodeMaps_) { + for (auto& nodeVec : elem.second) { + auto emptyVector = std::vector>(); + nodeVec.second->swap(emptyVector); + } + } + std::vector rootNodeType = { + WindowRootNodeType::ABOVE_WINDOW_NODE, + WindowRootNodeType::APP_WINDOW_NODE, + WindowRootNodeType::BELOW_WINDOW_NODE + }; + for (size_t index = 0; index < rootNodeType.size(); ++index) { + auto rootType = rootNodeType[index]; + auto rootNode = windowNodeContainer_->GetRootNode(rootType); + if (rootNode == nullptr) { + WLOGFE("rootNode is nullptr, %{public}d", rootType); + } + for (auto& node : rootNode->children_) { + AddWindowNodeOnWindowTree(node, rootType); + } + } +} + +void DisplayGroupController::ProcessCrossNodes(DisplayStateChangeType type) +{ + WLOGFI("ProcessCrossNodes"); +} + +void DisplayGroupController::UpdateWindowShowingDisplays(const sptr& node, const Rect& requestRect) +{ + WLOGFI("UpdateWindowShowingDisplays"); +} + +void DisplayGroupController::UpdateWindowDisplayIdIfNeeded(const sptr& node, + const std::vector& curShowingDisplays) +{ + WLOGFI("UpdateWindowDisplayIdIfNeeded"); +} + +void DisplayGroupController::CalculateNodeAbsoluteCordinate(const sptr& node) +{ + WLOGFI("CalculateNodeAbsoluteCordinate"); +} + +void DisplayGroupController::PreProcessWindowNode(const sptr& node, WindowUpdateType type) +{ + if (!windowNodeContainer_->GetLayoutPolicy()->IsMultiDisplay()) { + if (type == WindowUpdateType::WINDOW_UPDATE_ADDED) { + std::vector curShowingDisplays = { node->GetDisplayId() }; + node->SetShowingDisplays(curShowingDisplays); + for (auto& childNode : node->children_) { + PreProcessWindowNode(childNode, type); + } + } + WLOGFI("Current mode is not muti-display"); + return; + } +} + +void DisplayGroupController::UpdateWindowDisplayId(const sptr& node, DisplayId newDisplayId) +{ + WLOGFI("UpdateWindowDisplayId"); +} + +void DisplayGroupController::MoveCrossNodeToTargetDisplay(const sptr& node, DisplayId targetDisplayId) +{ + WLOGFI("MoveCrossNodeToTargetDisplay"); +} + +void DisplayGroupController::MoveNotCrossNodeToDefaultDisplay(const sptr& node, DisplayId displayId) +{ + WLOGFI("MoveNotCrossNodeToDefaultDisplay"); +} + +void DisplayGroupController::ProcessNotCrossNodesOnDestroiedDisplay(DisplayId displayId, + std::vector& windowIds) +{ + WLOGFI("ProcessNotCrossNodesOnDestroiedDisplay"); +} + +void DisplayGroupController::ProcessDisplayCreate(DisplayId displayId, + const std::map>& displayInfoMap) +{ + if (displayInfosMap_.find(displayId) != displayInfosMap_.end() || + displayInfoMap.size() != (displayInfosMap_.size() + 1)) { + WLOGFE("current display is exited or displayInfo map size is error, displayId: %{public}" PRIu64"", displayId); + return; + } + + defaultDisplayId_ = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + WLOGFI("defaultDisplay, displayId: %{public}" PRIu64"", defaultDisplayId_); + + windowNodeContainer_->GetAvoidController()->UpdateAvoidNodesMap(displayId, true); + InitNewDisplay(displayId); + + // window pair for split window + auto windowPair = new WindowPair(displayId, windowNodeMaps_); + windowPairMap_.insert(std::make_pair(displayId, windowPair)); + + // modify RSTree and windowNodeMaps for cross-display nodes + ProcessCrossNodes(DisplayStateChangeType::CREATE); + UpdateWindowNodeMaps(); + + for (auto& elem : displayInfoMap) { + auto iter = displayInfosMap_.find(elem.first); + const auto& displayInfo = elem.second; + Rect displayRect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), + displayInfo->GetWidth(), displayInfo->GetHeight() }; + if (iter != displayInfosMap_.end()) { + displayRectMap_[elem.first] = displayRect; + displayInfosMap_[elem.first] = displayInfo; + } else { + displayRectMap_.insert(std::make_pair(elem.first, displayRect)); + displayInfosMap_.insert(std::make_pair(elem.first, displayInfo)); + } + WLOGFI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", + elem.first, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); + } + windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayCreate(displayId, displayRectMap_); +} + +void DisplayGroupController::ProcessDisplayDestroy(DisplayId displayId, + const std::map>& displayInfoMap, + std::vector& windowIds) +{ + if (displayInfosMap_.find(displayId) == displayInfosMap_.end() || + (displayInfoMap.size() + 1) != displayInfosMap_.size()) { + WLOGFE("can not find current display or displayInfo map size is error, displayId: %{public}" PRIu64"", + displayId); + return; + } + + windowNodeContainer_->GetAvoidController()->UpdateAvoidNodesMap(displayId, false); + + // delete nodes and map element of deleted display + ProcessNotCrossNodesOnDestroiedDisplay(displayId, windowIds); + // modify RSTree and windowNodeMaps for cross-display nodes + ProcessCrossNodes(DisplayStateChangeType::DESTROY); + UpdateWindowNodeMaps(); + ClearMapOfDestroiedDisplay(displayId); + + for (auto& elem : displayInfoMap) { + auto iter = displayInfosMap_.find(elem.first); + const auto& displayInfo = elem.second; + Rect displayRect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), + displayInfo->GetWidth(), displayInfo->GetHeight() }; + if (iter != displayInfosMap_.end()) { + displayRectMap_[elem.first] = displayRect; + displayInfosMap_[elem.first] = displayInfo; + WLOGFI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", + elem.first, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); + } + } + + windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayDestroy(displayId, displayRectMap_); +} + +void DisplayGroupController::ProcessDisplayChange(DisplayId displayId, + const std::map>& displayInfoMap, + DisplayStateChangeType type) +{ + const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); + if (displayInfosMap_.find(displayId) == displayInfosMap_.end()) { + WLOGFE("can not find current display, displayId: %{public}" PRIu64", type: %{public}d", displayId, type); + return; + } + WLOGFI("display change, displayId: %{public}" PRIu64", type: %{public}d", displayId, type); + switch (type) { + case DisplayStateChangeType::UPDATE_ROTATION: { + displayInfosMap_[displayId]->SetRotation(displayInfo->GetRotation()); + [[fallthrough]]; + } + case DisplayStateChangeType::SIZE_CHANGE: { + displayInfosMap_[displayId]->SetWidth(displayInfo->GetWidth()); + displayInfosMap_[displayId]->SetHeight(displayInfo->GetHeight()); + ProcessDisplaySizeChangeOrRotation(displayId, displayInfoMap, type); + break; + } + case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { + displayInfosMap_[displayId]->SetVirtualPixelRatio(displayInfo->GetVirtualPixelRatio()); + windowNodeContainer_->GetLayoutPolicy()->LayoutWindowTree(displayId); + break; + } + default: { + break; + } + } +} + +void DisplayGroupController::ProcessDisplaySizeChangeOrRotation(DisplayId displayId, + const std::map>& displayInfoMap, DisplayStateChangeType type) +{ + // modify RSTree and windowNodeMaps for cross-display nodes + ProcessCrossNodes(type); + UpdateWindowNodeMaps(); + for (auto& elem : displayInfoMap) { + auto iter = displayInfosMap_.find(elem.first); + const auto& displayInfo = elem.second; + Rect displayRect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), + displayInfo->GetWidth(), displayInfo->GetHeight() }; + if (iter != displayInfosMap_.end()) { + displayRectMap_[elem.first] = displayRect; + displayInfosMap_[elem.first] = displayInfo; + WLOGFI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]", + elem.first, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_); + } + } + windowNodeContainer_->GetLayoutPolicy()->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap_); +} + +void DisplayGroupController::ClearMapOfDestroiedDisplay(DisplayId displayId) +{ + sysBarTintMaps_.erase(displayId); + sysBarNodeMaps_.erase(displayId); + windowNodeMaps_.erase(displayId); + displayRectMap_.erase(displayId); + displayInfosMap_.erase(displayId); + windowPairMap_.erase(displayId); +} + +sptr DisplayGroupController::GetWindowPairByDisplayId(DisplayId displayId) +{ + if (windowPairMap_.find(displayId) != windowPairMap_.end()) { + return windowPairMap_[displayId]; + } + return nullptr; +} +} +} diff --git a/wmserver/src/input_window_monitor.cpp b/wmserver/src/input_window_monitor.cpp index f34210ef3a70d15ed704d3663900ba9ab260ed82..79892f1567ce834f8fc87b726c34be0db90855d4 100644 --- a/wmserver/src/input_window_monitor.cpp +++ b/wmserver/src/input_window_monitor.cpp @@ -80,7 +80,7 @@ void InputWindowMonitor::UpdateInputWindowByDisplayId(DisplayId displayId) WLOGFE("There is no display for this window action."); return; } - WLOGFI("update display info to IMS."); + WLOGFI("update display info to IMS, displayId: %{public}" PRIu64"", displayId); MMI::InputManager::GetInstance()->UpdateDisplayInfo(physicalDisplays_, logicalDisplays_); } diff --git a/wmserver/src/starting_window.cpp b/wmserver/src/starting_window.cpp index a6ac2eed885d97432e1b668b04e41a5e818587db..5136151c85f40273695e587239968f9374b56675 100644 --- a/wmserver/src/starting_window.cpp +++ b/wmserver/src/starting_window.cpp @@ -136,10 +136,13 @@ void StartingWindow::UpdateRSTree(sptr& node) dms.UpdateRSTree(displayId, node->leashWinSurfaceNode_, true); node->leashWinSurfaceNode_->AddChild(node->startingWinSurfaceNode_, -1); } else { // hot start - if (node->leashWinSurfaceNode_) { // to app - dms.UpdateRSTree(displayId, node->leashWinSurfaceNode_, true); - } else { // to launcher - dms.UpdateRSTree(displayId, node->surfaceNode_, true); + const auto& displayIdVec = node->GetShowingDisplays(); + for (auto& shownDisplayId : displayIdVec) { + if (node->leashWinSurfaceNode_) { // to app + dms.UpdateRSTree(shownDisplayId, node->leashWinSurfaceNode_, true); + } else { // to launcher + dms.UpdateRSTree(shownDisplayId, node->surfaceNode_, true); + } } } } diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 0420c8033f8e5597b0660e893f0f25f73d396aea..b1fe2c550a455094d6aa981d1572ca717c14da5f 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -398,11 +398,6 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat isScreenLocked_ = false; break; } - case DisplayStateChangeType::SIZE_CHANGE: - case DisplayStateChangeType::UPDATE_ROTATION: { - ProcessDisplayChange(displayId, type); - break; - } case DisplayStateChangeType::CREATE: { windowRoot_->ProcessDisplayCreate(displayId); break; @@ -411,10 +406,10 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat windowRoot_->ProcessDisplayDestroy(displayId); break; } + case DisplayStateChangeType::SIZE_CHANGE: + case DisplayStateChangeType::UPDATE_ROTATION: case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { ProcessDisplayChange(displayId, type); - const sptr displayInfo_ = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); - windowRoot_->NotifyVirtualPixelRatioChange(displayInfo_); break; } default: { @@ -471,13 +466,11 @@ void WindowController::ProcessDisplayChange(DisplayId displayId, DisplayStateCha } switch (type) { case DisplayStateChangeType::SIZE_CHANGE: - case DisplayStateChangeType::UPDATE_ROTATION: { + case DisplayStateChangeType::UPDATE_ROTATION: ProcessSystemBarChange(displayInfo); - windowRoot_->ProcessDisplayChange(displayInfo, type); - break; - } + [[fallthrough]]; case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { - windowRoot_->ProcessDisplayChange(displayInfo, type); + windowRoot_->ProcessDisplayChange(displayId, type); break; } default: { diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index ad5c0071c72d04b9bc3c51215588695da3585273..6cf868bf540f3f8a2d849d87546f6136c6b6aa16 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -47,16 +47,117 @@ void WindowLayoutPolicy::Reorder() WLOGFI("WindowLayoutPolicy::Reorder"); } -void WindowLayoutPolicy::UpdateDisplayInfo(const std::map& displayRectMap) +void WindowLayoutPolicy::LimitWindowToBottomRightCorner(const sptr& node) { - displayRectMap_.clear(); - for (auto& displayRect : displayRectMap) { - displayRectMap_.insert(displayRect); + WLOGFI("LimitWindowToBottomRightCorner"); +} + +void WindowLayoutPolicy::UpdateDisplayGroupRect() +{ + WLOGFI("UpdateDisplayGroupRect"); +} + +void WindowLayoutPolicy::UpdateDisplayGroupLimitRect_() +{ + WLOGFI("UpdateDisplayGroupLimitRect_"); +} + +void WindowLayoutPolicy::UpdateNodeAbsoluteCordinate(const sptr& node, + const Rect& srcDisplayRect, + const Rect& dstDisplayRect) +{ + WLOGFI("UpdateNodeAbsoluteCordinate"); +} + +bool WindowLayoutPolicy::IsMultiDisplay() +{ + return isMultiDisplay_; +} + +void WindowLayoutPolicy::UpdateMultiDisplayFlag() +{ + if (displayRectMap_.size() > 1) { + isMultiDisplay_ = true; + WLOGFI("current mode is muti-display"); + } else { + isMultiDisplay_ = false; + WLOGFI("current mode is not muti-display"); } +} + +void WindowLayoutPolicy::UpdateNodesAbsoluteCordinatesInAllDisplay(DisplayId displayId, + const Rect& srcDisplayRect, + const Rect& dstDisplayRect) +{ + WLOGFI("UpdateNodesAbsoluteCordinatesInAllDisplay"); +} + +void WindowLayoutPolicy::PostProcessWhenDisplayChange() +{ + UpdateMultiDisplayFlag(); + UpdateDisplayGroupRect(); Launch(); - for (auto& displayRect : displayRectMap) { - LayoutWindowTree(displayRect.first); + for (auto& elem : displayRectMap_) { + LayoutWindowTree(elem.first); + WLOGFI("LayoutWindowTree, displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, " + "%{public}d]", elem.first, elem.second.posX_, elem.second.posY_, elem.second.width_, elem.second.height_); + } +} + +void WindowLayoutPolicy::ProcessDisplayCreate(DisplayId displayId, const std::map& displayRectMap) +{ + for (auto& elem : displayRectMap) { + auto iter = displayRectMap_.find(elem.first); + if (iter != displayRectMap_.end()) { + UpdateNodesAbsoluteCordinatesInAllDisplay(elem.first, iter->second, elem.second); + iter->second = elem.second; + } else { + if (elem.first != displayId) { + WLOGFE("Wrong display, displayId: %{public}" PRIu64"", displayId); + return; + } + displayRectMap_.insert(std::make_pair(displayId, elem.second)); + } + } + + PostProcessWhenDisplayChange(); + WLOGFI("Process display create, displayId: %{public}" PRIu64"", displayId); +} + +void WindowLayoutPolicy::ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap) +{ + for (auto oriIter = displayRectMap_.begin(); oriIter != displayRectMap_.end();) { + auto newIter = displayRectMap.find(oriIter->first); + if (newIter != displayRectMap.end()) { + UpdateNodesAbsoluteCordinatesInAllDisplay(oriIter->first, oriIter->second, newIter->second); + oriIter->second = newIter->second; + ++oriIter; + } else { + if (oriIter->first != displayId) { + WLOGFE("Wrong display, displayId: %{public}" PRIu64"", displayId); + return; + } + displayRectMap_.erase(oriIter++); + } } + + PostProcessWhenDisplayChange(); + WLOGFI("Process display destroy, displayId: %{public}" PRIu64"", displayId); +} + +void WindowLayoutPolicy::ProcessDisplaySizeChangeOrRotation(DisplayId displayId, + const std::map& displayRectMap) +{ + for (auto& elem : displayRectMap) { + auto iter = displayRectMap_.find(elem.first); + if (iter != displayRectMap_.end()) { + UpdateNodesAbsoluteCordinatesInAllDisplay(elem.first, iter->second, elem.second); + iter->second = elem.second; + } + } + + PostProcessWhenDisplayChange(); + WLOGFI("Process display change, displayId: %{public}" PRIu64"", displayId); } void WindowLayoutPolicy::LayoutWindowNodesByRootType(const std::vector>& nodeVec) @@ -98,6 +199,7 @@ void WindowLayoutPolicy::LayoutWindowNode(const sptr& node) UpdateLayoutRect(node); if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { UpdateLimitRect(node, limitRectMap_[node->GetDisplayId()]); + UpdateDisplayGroupLimitRect_(); } } for (auto& childNode : node->children_) { @@ -115,8 +217,8 @@ void WindowLayoutPolicy::UpdateClientRectAndResetReason(const sptr& { auto reason = node->GetWindowSizeChangeReason(); if (node->GetWindowToken()) { - WLOGFE("notify client id: %{public}d windowRect:[%{public}d, %{public}d, %{public}u, %{public}u]", - node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + WLOGFI("notify client id: %{public}d, windowRect:[%{public}d, %{public}d, %{public}u, %{public}u], reason: " + "%{public}u", node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_, reason); node->GetWindowToken()->UpdateWindowRect(winRect, node->GetDecoStatus(), reason); } if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::DRAG_END) { @@ -217,12 +319,13 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, const sptrSetHotZoneRect(rect); } -void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const +void WindowLayoutPolicy::LimitFloatingWindowSize(const sptr& node, + const Rect& displayRect, + Rect& winRect) const { float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); - uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); WindowType windowType = node->GetWindowType(); WindowMode windowMode = node->GetWindowMode(); @@ -243,10 +346,23 @@ void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rec winRect.width_ = std::min(static_cast(MAX_FLOATING_SIZE * virtualPixelRatio), winRect.width_); winRect.height_ = std::min(static_cast(MAX_FLOATING_SIZE * virtualPixelRatio), winRect.height_); } +} + +void WindowLayoutPolicy::LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const +{ + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + + Rect limitRect; + // if is corss-display window, the limit rect should be full limitRect + if (node->isShowingOnMultiDisplays_) { + limitRect = displayGroupLimitRect_; + } else { + limitRect = limitRectMap_[node->GetDisplayId()]; + } - const Rect& limitRect = limitRectMap_[node->GetDisplayId()]; // limit position of the main floating window(window which support dragging) - if (WindowHelper::IsMainFloatingWindow(windowType, windowMode)) { + if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { winRect.posY_ = std::max(limitRect.posY_, winRect.posY_); winRect.posY_ = std::min(limitRect.posY_ + static_cast(limitRect.height_ - windowTitleBarH), winRect.posY_); @@ -356,5 +472,10 @@ void WindowLayoutPolicy::UpdateSurfaceBounds(const sptr& node, const node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } } + +Rect WindowLayoutPolicy::GetDisplayGroupRect() const +{ + return displayGroupRect_; +} } } diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index 4e60f19f7f9099e2153e63ae1ff057642a4511b0..9fcfd9c8fe98b61179e0badbfb75e8fb51caf6fc 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -61,6 +61,7 @@ void WindowLayoutPolicyCascade::Reset() InitSplitRects(iter.first); InitLimitRects(iter.first); } + displayGroupLimitRect_ = displayGroupRect_; } void WindowLayoutPolicyCascade::InitAllRects() @@ -69,6 +70,8 @@ void WindowLayoutPolicyCascade::InitAllRects() // init split and limit rects InitSplitRects(iter.first); InitLimitRects(iter.first); + // init full displayRect + displayGroupLimitRect_ = displayGroupRect_; // init cascade rect auto& windowNodeMap = windowNodeMaps_[iter.first]; LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::ABOVE_WINDOW_NODE])); @@ -94,6 +97,7 @@ void WindowLayoutPolicyCascade::LayoutWindowNode(const sptr& node) UpdateLimitRect(node, limitRectMap_[displayId]); UpdateSplitLimitRect(limitRectMap_[displayId], primaryLimitRect); UpdateSplitLimitRect(limitRectMap_[displayId], secondaryLimitRect); + UpdateDisplayGroupLimitRect_(); WLOGFI("priLimitRect: %{public}d %{public}d %{public}u %{public}u, " \ "secLimitRect: %{public}d %{public}d %{public}u %{public}u", primaryLimitRect.posX_, primaryLimitRect.posY_, primaryLimitRect.width_, primaryLimitRect.height_, secondaryLimitRect.posX_, @@ -235,18 +239,31 @@ void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptrGetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { // if divider, limit position LimitMoveBounds(winRect, node->GetDisplayId()); } - if (reason == WindowSizeChangeReason::DRAG) { // if drag window, limit size and position + + // if drag or move window, limit size and position + if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::MOVE) { if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { const Rect lastRect = node->GetWindowRect(); // fix rect in case of moving window when dragging winRect = WindowHelper::GetFixedWindowRectByLimitSize(winRect, lastRect, IsVerticalDisplay(node->GetDisplayId()), virtualPixelRatio); + + // if is mutiDisplay, the limit rect should be full limitRect when move or drag + Rect limitRect; + if (isMultiDisplay_) { + limitRect = displayGroupLimitRect_; + } else { + limitRect = limitRectMap_[node->GetDisplayId()]; + } winRect = WindowHelper::GetFixedWindowRectByLimitPosition(winRect, lastRect, - virtualPixelRatio, limitRectMap_[node->GetDisplayId()]); + virtualPixelRatio, limitRect); } + } else { + // Limit window to the maximum window size if size change is other reason, such as init window rect when show + LimitFloatingWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); + LimitMainFloatingWindowPosition(node, winRect); } - // Limit window to the maximum window size - LimitWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); + WLOGFI("After apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index e046e5dce0d1951e451aa2bcd9db3c872521ac28..f4a9c7bd03deb00bd002e6eedad5765a3cba11ae 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -56,6 +56,7 @@ void WindowLayoutPolicyTile::Launch() void WindowLayoutPolicyTile::InitAllRects() { + displayGroupLimitRect_ = displayGroupRect_; for (auto& iter : displayRectMap_) { DisplayId displayId = iter.first; limitRectMap_[displayId] = iter.second; @@ -293,7 +294,10 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr& node) UpdateFloatingLayoutRect(limitRect, winRect); } } - LimitWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); + + LimitFloatingWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); + LimitMainFloatingWindowPosition(node, winRect); + node->SetWindowRect(winRect); CalcAndSetNodeHotZone(winRect, node); UpdateClientRectAndResetReason(node, lastRect, winRect); diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index 4e6822c8af2cddef053a6fb52e79798575be14df..2aaf4724905b49b2fc8de1ebf95bdff33e820c29 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -147,6 +147,12 @@ void WindowNode::SetRequestedOrientation(Orientation orientation) property_->SetRequestedOrientation(orientation); } +void WindowNode::SetShowingDisplays(const std::vector& displayIdVec) +{ + showingDisplays_.clear(); + showingDisplays_.assign(displayIdVec.begin(), displayIdVec.end()); +} + void WindowNode::ResetWindowSizeChangeReason() { windowSizeChangeReason_ = WindowSizeChangeReason::UNDEFINED; @@ -287,5 +293,10 @@ Orientation WindowNode::GetRequestedOrientation() const { return property_->GetRequestedOrientation(); } + +std::vector WindowNode::GetShowingDisplays() const +{ + return showingDisplays_; +} } // namespace Rosen } // namespace OHOS diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 210fa0e234f4e88d85b22d641843b4fb05d28ab1..61bd4aa0675904e94812cefedf598621eeb6d3cb 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -22,7 +22,6 @@ #include #include "common_event_manager.h" -#include "display_manager_service_inner.h" #include "dm_common.h" #include "starting_window.h" #include "window_helper.h" @@ -51,16 +50,16 @@ WindowNodeContainer::WindowNodeContainer(const sptr& displayInfo) displayInfo->GetWidth(), displayInfo->GetHeight() }; displayRectMap_.insert(std::make_pair(displayId, displayRect)); displayInfosMap_.insert(std::make_pair(displayId, displayInfo)); - windowPair_ = new WindowPair(displayId, appWindowNode_); - // init window node maps - InitWindowNodeMapForDisplay(displayId); + // create mutiDisplayController and init nodes and systemBar map for display + displayGroupController_ = new DisplayGroupController(this, displayRectMap_, displayInfosMap_); + displayGroupController_->InitNewDisplay(displayId); // init layout policy layoutPolicys_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(displayRectMap_, - windowNodeMaps_, displayInfosMap_); + displayGroupController_->windowNodeMaps_, displayInfosMap_); layoutPolicys_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(displayRectMap_, - windowNodeMaps_, displayInfosMap_); + displayGroupController_->windowNodeMaps_, displayInfosMap_); layoutPolicy_ = layoutPolicys_[WindowLayoutMode::CASCADE]; layoutPolicy_->Launch(); @@ -68,9 +67,6 @@ WindowNodeContainer::WindowNodeContainer(const sptr& displayInfo) UpdateAvoidAreaFunc func = std::bind(&WindowNodeContainer::OnAvoidAreaChange, this, std::placeholders::_1, std::placeholders::_2); avoidController_ = new AvoidAreaController(displayId, func); - - // init systembar map - InitSysBarMapForDisplay(displayId); } WindowNodeContainer::~WindowNodeContainer() @@ -78,33 +74,6 @@ WindowNodeContainer::~WindowNodeContainer() Destroy(); } -void WindowNodeContainer::InitSysBarMapForDisplay(DisplayId displayId) -{ - SysBarNodeMap sysBarNodeMap { - { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, - { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, - }; - sysBarNodeMaps_.insert(std::make_pair(displayId, sysBarNodeMap)); - - SysBarTintMap sysBarTintMap { - { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarRegionTint() }, - { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() }, - }; - sysBarTintMaps_.insert(std::make_pair(displayId, sysBarTintMap)); -} - -void WindowNodeContainer::InitWindowNodeMapForDisplay(DisplayId displayId) -{ - std::map>>> windowRootNodeMap; - windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::APP_WINDOW_NODE, - std::make_unique>>())); - windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::ABOVE_WINDOW_NODE, - std::make_unique>>())); - windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::BELOW_WINDOW_NODE, - std::make_unique>>())); - windowNodeMaps_.insert(std::make_pair(displayId, std::move(windowRootNodeMap))); -} - int WindowNodeContainer::GetWindowCountByType(WindowType windowType) { int windowNumber = 0; @@ -117,67 +86,6 @@ int WindowNodeContainer::GetWindowCountByType(WindowType windowType) return windowNumber; } -std::vector>* WindowNodeContainer::FindNodeVectorOfRoot(DisplayId displayId, WindowRootNodeType type) -{ - if (windowNodeMaps_.find(displayId) != windowNodeMaps_.end()) { - auto& rootNodemap = windowNodeMaps_[displayId]; - if (rootNodemap.find(type) != rootNodemap.end()) { - return rootNodemap[type].get(); - } - } - return nullptr; -} - -void WindowNodeContainer::AddWindowNodeInRootNodeVector(sptr& node, WindowRootNodeType rootType) -{ - std::vector>* rootNodeVectorPtr = FindNodeVectorOfRoot(node->GetDisplayId(), rootType); - if (rootNodeVectorPtr != nullptr) { - rootNodeVectorPtr->push_back(node); - WLOGFI("add node in node vector of root, windowId: %{public}d, rootType: %{public}d", - node->GetWindowId(), rootType); - } else { - WLOGFE("add node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", - node->GetWindowId(), rootType); - } -} - -void WindowNodeContainer::RemoveWindowNodeFromRootNodeVector(sptr& node, WindowRootNodeType rootType) -{ - std::vector>* rootNodeVectorPtr = FindNodeVectorOfRoot(node->GetDisplayId(), rootType); - if (rootNodeVectorPtr != nullptr) { - auto iter = std::remove(rootNodeVectorPtr->begin(), rootNodeVectorPtr->end(), node); - rootNodeVectorPtr->erase(iter, rootNodeVectorPtr->end()); - WLOGFI("remove node from node vector of root, windowId: %{public}d, rootType: %{public}d", - node->GetWindowId(), rootType); - } else { - WLOGFE("remove node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", - node->GetWindowId(), rootType); - } -} - -void WindowNodeContainer::UpdateWindowNodeMaps() -{ - for (auto& elem : windowNodeMaps_) { - for (auto& nodeVec : elem.second) { - auto emptyVector = std::vector>(); - nodeVec.second->swap(emptyVector); - } - } - - std::vector> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ }; - std::vector rootNodeType = { - WindowRootNodeType::ABOVE_WINDOW_NODE, - WindowRootNodeType::APP_WINDOW_NODE, - WindowRootNodeType::BELOW_WINDOW_NODE - }; - for (size_t index = 0; index < rootNodes.size(); ++index) { - auto rootType = rootNodeType[index]; - for (auto& node : rootNodes[index]->children_) { - AddWindowNodeInRootNodeVector(node, rootType); - } - } -} - WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr& node, const sptr& parentNode) { sptr root = FindRoot(node->GetWindowType()); @@ -202,7 +110,7 @@ WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr& node, c child->currentVisibility_ = child->requestedVisibility_; } if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { - sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node; + displayGroupController_->sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node; } } return WMError::WM_OK; @@ -219,14 +127,21 @@ WMError WindowNodeContainer::ShowInTransition(sptr& node) if (res != WMError::WM_OK) { return res; } - windowPair_->UpdateIfSplitRelated(node); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId()); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + windowPair->UpdateIfSplitRelated(node); UpdateWindowTree(node); if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { RaiseSplitRelatedWindowToTop(node); } + displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED); StartingWindow::UpdateRSTree(node); AssignZOrder(); + layoutPolicy_->AddWindowNode(node); WM_SCOPED_TRACE_END(); WLOGFI("ShowInTransition windowId: %{public}u end", node->GetWindowId()); @@ -240,12 +155,22 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrUpdateIfSplitRelated(node); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId()); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + windowPair->UpdateIfSplitRelated(node); UpdateWindowTree(node); if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { RaiseSplitRelatedWindowToTop(node); } - UpdateRSTree(node, true, node->isPlayAnimationShow_); + + displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED); + // add node on RSTree + for (auto& displayId : node->GetShowingDisplays()) { + UpdateRSTree(node, displayId, true, node->isPlayAnimationShow_); + } AssignZOrder(); } else { node->isPlayAnimationShow_ = false; @@ -270,8 +195,36 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptr& node, + const std::vector& lastShowingDisplays, + const std::vector& curShowingDisplays) +{ + // Update RSTree + for (auto& displayId : lastShowingDisplays) { + if (std::find(curShowingDisplays.begin(), curShowingDisplays.end(), displayId) == curShowingDisplays.end()) { + UpdateRSTree(node, displayId, false); + WLOGFI("remove from RSTree : %{public}" PRIu64"", displayId); + } + } + + for (auto& displayId : curShowingDisplays) { + if (std::find(lastShowingDisplays.begin(), lastShowingDisplays.end(), displayId) == lastShowingDisplays.end()) { + UpdateRSTree(node, displayId, true); + WLOGFI("add on RSTree : %{public}" PRIu64"", displayId); + } + } +} + WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpdateReason reason) { + // Preprocess node + const auto lastShowingDisplays = node->GetShowingDisplays(); + displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE); + const auto& curShowingDisplays = node->GetShowingDisplays(); + + // Update RSTree + UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays, curShowingDisplays); + if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) { SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId()); } @@ -287,6 +240,107 @@ WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpda return WMError::WM_OK; } +void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr& node) +{ + // remove this node from node vector of display + sptr root = FindRoot(node->GetWindowType()); + + // remove this node from parent + auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node); + if (iter != node->parent_->children_.end()) { + node->parent_->children_.erase(iter); + } else { + WLOGFE("can't find this node in parent"); + } + node->parent_ = nullptr; +} + +WMError WindowNodeContainer::RemoveWindowNode(sptr& node) +{ + if (node == nullptr) { + WLOGFE("window node or surface node is nullptr, invalid"); + return WMError::WM_ERROR_DESTROYED_OBJECT; + } + + if (node->parent_ == nullptr) { + WLOGFW("can't find parent of this node"); + } else { + RemoveWindowNodeFromWindowTree(node); + } + + node->requestedVisibility_ = false; + node->currentVisibility_ = false; + node->isCovered_ = true; + std::vector> infos = {new WindowVisibilityInfo(node->GetWindowId(), + node->GetCallingPid(), node->GetCallingUid(), false)}; + for (auto& child : node->children_) { + if (child->currentVisibility_) { + child->currentVisibility_ = false; + child->isCovered_ = true; + infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(), + child->GetCallingUid(), false)); + } + } + + displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); + + // Remove node from RSTree + for (auto& displayId : node->GetShowingDisplays()) { + UpdateRSTree(node, displayId, false, node->isPlayAnimationHide_); + } + auto emptyVec = std::vector(); + node->showingDisplays_.swap(emptyVec); + + displayGroupController_->UpdateWindowNodeMaps(); + + layoutPolicy_->RemoveWindowNode(node); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId()); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + windowPair->HandleRemoveWindow(node); + if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { + avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE); + NotifyIfSystemBarRegionChanged(node->GetDisplayId()); + } else { + NotifyIfSystemBarTintChanged(node->GetDisplayId()); + } + UpdateWindowVisibilityInfos(infos); + DumpScreenWindowTree(); + NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); + RcoveryScreenDefaultOrientationIfNeed(node->GetDisplayId()); + WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId()); + return WMError::WM_OK; +} + +WMError WindowNodeContainer::DestroyWindowNode(sptr& node, std::vector& windowIds) +{ + WMError ret = RemoveWindowNode(node); + if (ret != WMError::WM_OK) { + WLOGFE("RemoveWindowNode failed"); + return ret; + } + node->leashWinSurfaceNode_ = nullptr; + node->startingWinSurfaceNode_ = nullptr; + node->surfaceNode_ = nullptr; + windowIds.push_back(node->GetWindowId()); + + for (auto& child : node->children_) { // destroy sub window if exists + windowIds.push_back(child->GetWindowId()); + child->parent_ = nullptr; + if (child->surfaceNode_ != nullptr) { + WLOGFI("child surfaceNode set nullptr"); + child->surfaceNode_ = nullptr; + } + } + + // clear vector cache completely, swap with empty vector + auto emptyVector = std::vector>(); + node->children_.swap(emptyVector); + return WMError::WM_OK; +} + void WindowNodeContainer::UpdateSizeChangeReason(sptr& node, WindowSizeChangeReason reason) { if (!node->GetWindowToken()) { @@ -328,7 +382,7 @@ void WindowNodeContainer::UpdateWindowTree(sptr& node) parentNode->children_.insert(position, node); } -bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd, bool animationPlayed) +bool WindowNodeContainer::UpdateRSTree(sptr& node, DisplayId displayId, bool isAdd, bool animationPlayed) { WM_FUNCTION_TRACE(); if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) { @@ -336,9 +390,10 @@ bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd, bool return true; } static const bool IsWindowAnimationEnabled = ReadIsWindowAnimationEnabledProperty(); - DisplayId displayId = node->GetDisplayId(); auto updateRSTreeFunc = [&]() { auto& dms = DisplayManagerServiceInner::GetInstance(); + WLOGFI("UpdateRSTree windowId: %{public}d, displayId: %{public}" PRIu64", isAdd: %{public}d", + node->GetWindowId(), displayId, isAdd); if (isAdd) { if (node->leashWinSurfaceNode_) { dms.UpdateRSTree(displayId, node->leashWinSurfaceNode_, true); @@ -376,94 +431,9 @@ bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd, bool return true; } -WMError WindowNodeContainer::DestroyWindowNode(sptr& node, std::vector& windowIds) -{ - WMError ret = RemoveWindowNode(node); - if (ret != WMError::WM_OK) { - WLOGFE("RemoveWindowNode failed"); - return ret; - } - node->leashWinSurfaceNode_ = nullptr; - node->startingWinSurfaceNode_ = nullptr; - node->surfaceNode_ = nullptr; - windowIds.push_back(node->GetWindowId()); - - for (auto& child : node->children_) { // destroy sub window if exists - windowIds.push_back(child->GetWindowId()); - child->parent_ = nullptr; - if (child->surfaceNode_ != nullptr) { - WLOGFI("child surfaceNode set nullptr"); - child->surfaceNode_ = nullptr; - } - } - auto emptyVector = std::vector>(); - node->children_.swap(emptyVector); - return WMError::WM_OK; -} - -void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr& node) -{ - // remove this node from node vector of display - sptr root = FindRoot(node->GetWindowType()); - - // remove this node from parent - auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node); - if (iter != node->parent_->children_.end()) { - node->parent_->children_.erase(iter); - } else { - WLOGFE("can't find this node in parent"); - } - node->parent_ = nullptr; -} - -WMError WindowNodeContainer::RemoveWindowNode(sptr& node) -{ - if (node == nullptr) { - WLOGFE("window node or surface node is nullptr, invalid"); - return WMError::WM_ERROR_DESTROYED_OBJECT; - } - - if (node->parent_ == nullptr) { - WLOGFW("can't find parent of this node"); - } else { - RemoveWindowNodeFromWindowTree(node); - } - - node->requestedVisibility_ = false; - node->currentVisibility_ = false; - node->isCovered_ = true; - std::vector> infos = {new WindowVisibilityInfo(node->GetWindowId(), - node->GetCallingPid(), node->GetCallingUid(), false)}; - for (auto& child : node->children_) { - if (child->currentVisibility_) { - child->currentVisibility_ = false; - child->isCovered_ = true; - infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(), - child->GetCallingUid(), false)); - } - } - UpdateRSTree(node, false, node->isPlayAnimationHide_); - UpdateWindowNodeMaps(); - layoutPolicy_->RemoveWindowNode(node); - windowPair_->HandleRemoveWindow(node); - if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { - avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE); - NotifyIfSystemBarRegionChanged(node->GetDisplayId()); - } else { - NotifyIfSystemBarTintChanged(node->GetDisplayId()); - } - UpdateWindowVisibilityInfos(infos); - DumpScreenWindowTree(); - NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); - RcoveryScreenDefaultOrientationIfNeed(node->GetDisplayId()); - node->isPlayAnimationHide_ = false; - WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId()); - return WMError::WM_OK; -} - void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed(DisplayId displayId) { - if (windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]->empty()) { + if (displayGroupController_->windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]->empty()) { WLOGFI("appWindowNode_ child is empty in display %{public}" PRIu64"", displayId); DisplayManagerServiceInner::GetInstance(). SetOrientationFromWindow(displayId, Orientation::UNSPECIFIED); @@ -472,6 +442,7 @@ void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed(DisplayId displa const std::vector& WindowNodeContainer::Destroy() { + // clear vector cache completely, swap with empty vector auto emptyVector = std::vector(); removedIds_.swap(emptyVector); for (auto& node : belowAppWindowNode_->children_) { @@ -605,7 +576,7 @@ void WindowNodeContainer::AssignZOrder() return false; }; TraverseWindowTree(func, false); - UpdateWindowNodeMaps(); + displayGroupController_->UpdateWindowNodeMaps(); } WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId) @@ -670,6 +641,33 @@ uint32_t WindowNodeContainer::GetActiveWindow() const return activeWindow_; } +sptr WindowNodeContainer::GetLayoutPolicy() const +{ + return layoutPolicy_; +} + +sptr WindowNodeContainer::GetAvoidController() const +{ + return avoidController_; +} + +sptr WindowNodeContainer::GetMutiDisplayController() const +{ + return displayGroupController_; +} + +sptr WindowNodeContainer::GetRootNode(WindowRootNodeType type) const +{ + if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) { + return aboveAppWindowNode_; + } else if (type == WindowRootNodeType::APP_WINDOW_NODE) { + return appWindowNode_; + } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) { + return belowAppWindowNode_; + } + return nullptr; +} + void WindowNodeContainer::HandleKeepScreenOn(const sptr& node, bool requireLock) { if (requireLock && node->keepScreenLock_ == nullptr) { @@ -763,7 +761,7 @@ void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) WM_FUNCTION_TRACE(); auto expectSystemBarProp = GetExpectImmersiveProperty(); SystemBarRegionTints tints; - SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; + SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId]; for (auto it : sysBarTintMap) { auto expectProp = expectSystemBarProp.find(it.first)->second; if (it.second.prop_ == expectProp) { @@ -782,8 +780,8 @@ void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) { WM_FUNCTION_TRACE(); SystemBarRegionTints tints; - SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; - SysBarNodeMap& sysBarNodeMap = sysBarNodeMaps_[displayId]; + SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId]; + SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId]; for (auto it : sysBarTintMap) { // split screen mode not support yet auto sysNode = sysBarNodeMap[it.first]; if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) { @@ -809,7 +807,7 @@ void WindowNodeContainer::NotifySystemBarDismiss(sptr& node) } SystemBarRegionTints tints; auto& sysBarPropMapNode = node->GetSystemBarProperty(); - SysBarTintMap& sysBarTintMap = sysBarTintMaps_[node->GetDisplayId()]; + SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[node->GetDisplayId()]; for (auto it : sysBarPropMapNode) { it.second.enable_ = false; node->SetSystemBarProperty(it.first, it.second); @@ -827,13 +825,13 @@ void WindowNodeContainer::NotifySystemBarDismiss(sptr& node) void WindowNodeContainer::NotifySystemBarTints(std::vector displayIdVec) { WM_FUNCTION_TRACE(); - if (displayIdVec.size() != sysBarTintMaps_.size()) { + if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) { WLOGE("the number of display is error"); } for (auto displayId : displayIdVec) { SystemBarRegionTints tints; - SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; + SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId]; for (auto it : sysBarTintMap) { WLOGFI("system bar cur notify, type: %{public}d, " \ "visible: %{public}d, color: %{public}x | %{public}x, " \ @@ -1118,7 +1116,12 @@ void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr& node) if (node == nullptr) { return; } - std::vector> orderedPair = windowPair_->GetOrderedPair(node); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId()); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return; + } + std::vector> orderedPair = windowPair->GetOrderedPair(node); RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_); AssignZOrder(); return; @@ -1335,10 +1338,15 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, Displa WLOGFE("invalid layout mode"); return WMError::WM_ERROR_INVALID_PARAM; } + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } if (layoutMode_ != dstMode) { if (layoutMode_ == WindowLayoutMode::CASCADE) { layoutPolicy_->Reset(); - windowPair_->Clear(); + windowPair->Clear(); } layoutMode_ = dstMode; layoutPolicy_->Clean(); @@ -1349,7 +1357,7 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, Displa WLOGFI("Current layout mode is already: %{public}d", static_cast(dstMode)); } if (reorder) { - windowPair_->Clear(); + windowPair->Clear(); layoutPolicy_->Reorder(); DumpScreenWindowTree(); } @@ -1443,35 +1451,6 @@ void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr& windowIds) -{ - WLOGFI("Move window nodes when destroy display"); -} - -void WindowNodeContainer::ProcessDisplayCreate(const sptr& displayInfo) -{ - DisplayId displayId = displayInfo->GetDisplayId(); - Rect displayRect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), - displayInfo->GetWidth(), displayInfo->GetHeight() }; - AddDisplay(displayInfo); - avoidController_->UpdateAvoidNodesMap(displayId, true); - InitSysBarMapForDisplay(displayId); - InitWindowNodeMapForDisplay(displayId); - displayRectMap_.insert(std::make_pair(displayId, displayRect)); - layoutPolicy_->UpdateDisplayInfo(displayRectMap_); -} - -void WindowNodeContainer::ProcessDisplayDestroy(DisplayId displayId, std::vector& windowIds) -{ - WLOGFI("Process display destroy"); -} - -void WindowNodeContainer::ProcessDisplayChange(DisplayId displayId, const Rect& displayRect) -{ - displayRectMap_[displayId] = displayRect; - layoutPolicy_->UpdateDisplayInfo(displayRectMap_); -} - void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const { std::vector> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ }; @@ -1548,6 +1527,7 @@ bool WindowNodeContainer::TraverseFromBottomToTop(sptr node, const W void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector>& infos) { + // clear vector cache completely, swap with empty vector auto emptyVector = std::vector(); currentCoveredArea_.swap(emptyVector); WindowNodeOperationFunc func = [this, &infos](sptr node) { @@ -1594,6 +1574,11 @@ float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const return layoutPolicy_->GetVirtualPixelRatio(displayId); } +Rect WindowNodeContainer::GetDisplayGroupRect() const +{ + return layoutPolicy_->GetDisplayGroupRect(); +} + bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty() { if (access(DISABLE_WINDOW_ANIMATION_PATH, F_OK) == 0) { @@ -1621,7 +1606,12 @@ WMError WindowNodeContainer::SetWindowMode(sptr& node, WindowMode ds node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE); } node->SetWindowMode(dstMode); - windowPair_->UpdateIfSplitRelated(node); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId()); + if (windowPair == nullptr) { + WLOGFE("Window pair is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + windowPair->UpdateIfSplitRelated(node); if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && WindowHelper::IsAppWindow(node->GetWindowType())) { // minimize other app window @@ -1658,39 +1648,6 @@ void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeH hotZones.secondary_.height_ = displayRect.height_; } -void WindowNodeContainer::UpdateVirtualPixelRatio(DisplayId displayId, float virtualPixelRatio) -{ - layoutPolicy_->LayoutWindowTree(displayId); -} - -void WindowNodeContainer::SetDisplaySize(DisplayId displayId, uint32_t width, uint32_t height) -{ - if (displayInfosMap_.find(displayId) == std::end(displayInfosMap_)) { - return; - } - displayInfosMap_[displayId]->SetWidth(width); - displayInfosMap_[displayId]->SetHeight(height); - displayRectMap_[displayId].width_ = width; - displayRectMap_[displayId].height_ = height; - layoutPolicy_->UpdateDisplayInfo(displayRectMap_); -} - -void WindowNodeContainer::SetDisplayRotation(DisplayId displayId, Rotation rotation) -{ - if (displayInfosMap_.find(displayId) == std::end(displayInfosMap_)) { - return; - } - displayInfosMap_[displayId]->SetRotation(rotation); -} - -void WindowNodeContainer::SetDisplayVirtualPixelRatio(DisplayId displayId, float virtualPixelRatio) -{ - if (displayInfosMap_.find(displayId) == std::end(displayInfosMap_)) { - return; - } - displayInfosMap_[displayId]->SetVirtualPixelRatio(virtualPixelRatio); -} - float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) const { if (displayInfosMap_.find(displayId) == std::end(displayInfosMap_)) { @@ -1699,22 +1656,6 @@ float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) cons return displayInfosMap_.at(displayId)->GetVirtualPixelRatio(); } -void WindowNodeContainer::AddDisplay(const sptr& displayInfo) -{ - DisplayId id = displayInfo->GetDisplayId(); - if (displayInfosMap_.find(id) != std::end(displayInfosMap_)) { - displayInfosMap_[id] = displayInfo; - return; - } - displayInfosMap_.insert(std::make_pair(id, displayInfo)); -} - -void WindowNodeContainer::DeleteDisplay(const sptr& displayInfo) -{ - DisplayId id = displayInfo->GetDisplayId(); - displayInfosMap_.erase(id); -} - sptr WindowNodeContainer::GetDisplayInfo(DisplayId displayId) { if (displayInfosMap_.find(displayId) != std::end(displayInfosMap_)) { diff --git a/wmserver/src/window_pair.cpp b/wmserver/src/window_pair.cpp index cbdf391683343094010f1dafdf849b8a7a7cda50..f3475228f83fb5e7d8ce2b4686682213604d95d6 100644 --- a/wmserver/src/window_pair.cpp +++ b/wmserver/src/window_pair.cpp @@ -29,8 +29,8 @@ namespace { const std::string SPLIT_SCREEN_EVENT_NAME = "common.event.SPLIT_SCREEN"; } -WindowPair::WindowPair(const DisplayId& displayId, sptr& appNode) - : displayId_(displayId), appWindowNode_(appNode) { +WindowPair::WindowPair(const DisplayId& displayId, WindowNodeMaps& windowNodeMaps) + : displayId_(displayId), windowNodeMaps_(windowNodeMaps) { } WindowPair::~WindowPair() @@ -228,7 +228,9 @@ sptr WindowPair::FindPairableWindow(sptr& node) if (!node->IsSplitMode()) { return nullptr; } - for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) { + + auto& appNodeVec = *(windowNodeMaps_[displayId_][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto iter = appNodeVec.rbegin(); iter != appNodeVec.rend(); iter++) { auto pairNode = *iter; if (pairNode == nullptr) { continue; diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 031474fdad51735d40096d95bcd698a89171b58f..b59fae08ba767a6aeb6969b67b41a1e12978f6d4 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -894,21 +894,34 @@ void WindowRoot::FocusFaultDetection() const void WindowRoot::ProcessExpandDisplayCreate(DisplayId displayId, ScreenId screenGroupId) { const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); - if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { - WLOGFE("get display failed or get invailed display info, displayId :%{public}" PRIu64 "", displayId); - return; - } - auto container = windowNodeContainerMap_[screenGroupId]; - if (container == nullptr) { - WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); - return; + if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { + WLOGFE("get display failed or get invailed display info, displayId :%{public}" PRIu64 "", displayId); + return; + } + auto container = windowNodeContainerMap_[screenGroupId]; + if (container == nullptr) { + WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); + } + // add displayId in displayId vector + displayIdMap_[screenGroupId].push_back(displayId); + + WLOGFI("[Display Create] before add new display, displayId: %{public}" PRIu64"", displayId); + + auto displayInfoMap = GetAllDisplayInfos(displayIdMap_[screenGroupId]); + container->GetMutiDisplayController()->ProcessDisplayCreate(displayId, displayInfoMap); + + WLOGFI("[Display Create] Container exist, add new display, displayId: %{public}" PRIu64"", displayId); +} + +std::map> WindowRoot::GetAllDisplayInfos(const std::vector& displayIdVec) +{ + std::map> displayInfoMap; + for (auto& displayId : displayIdVec) { + const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); + displayInfoMap.insert(std::make_pair(displayId, displayInfo)); + WLOGFI("Get latest displayInfo, displayId: %{public}" PRIu64"", displayId); } - // add displayId in displayIdMap - displayIdMap_[screenGroupId].push_back(displayId); - container->ProcessDisplayCreate(displayInfo); - WLOGFI("[Display Create] Container exist, add new display, displayId: %{public}" PRIu64", Rect: [" - "%{public}d, %{public}d, %{public}u, %{public}u]", displayId, displayInfo->GetOffsetX(), - displayInfo->GetOffsetY(), displayInfo->GetWidth(), displayInfo->GetHeight()); + return displayInfoMap; } void WindowRoot::ProcessDisplayCreate(DisplayId displayId) @@ -919,8 +932,8 @@ void WindowRoot::ProcessDisplayCreate(DisplayId displayId) CreateWindowNodeContainer(displayId); WLOGFI("[Display Create] Create new container for display, displayId: %{public}" PRIu64"", displayId); } else { - if (std::find(displayIdMap_[screenGroupId].begin(), displayIdMap_[screenGroupId].end(), displayId) != - displayIdMap_[screenGroupId].end()) { + auto& displayIdVec = displayIdMap_[screenGroupId]; + if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { WLOGFI("[Display Create] Current display is already exist, displayId: %{public}" PRIu64"", displayId); return; } @@ -930,12 +943,42 @@ void WindowRoot::ProcessDisplayCreate(DisplayId displayId) void WindowRoot::ProcessDisplayDestroy(DisplayId displayId) { + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); + auto& displayIdVec = displayIdMap_[screenGroupId]; + auto iter = windowNodeContainerMap_.find(screenGroupId); + if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(), + displayIdVec.end(), displayId) == displayIdVec.end()) { + WLOGFE("[Display Destroy] could not find display, destroy failed, displayId: %{public}" PRIu64"", displayId); + return; + } + + // erase displayId in displayIdMap + auto displayIter = std::remove(displayIdVec.begin(), displayIdVec.end(), displayId); + displayIdVec.erase(displayIter, displayIdVec.end()); + + // container process display destroy + auto container = iter->second; + if (container == nullptr) { + WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); + return; + } + WLOGFI("[Display Destroy] displayId: %{public}" PRIu64"", displayId); + + std::vector needDestoryWindows; + auto displayInfoMap = GetAllDisplayInfos(displayIdVec); + container->GetMutiDisplayController()->ProcessDisplayDestroy(displayId, displayInfoMap, needDestoryWindows); + for (auto id : needDestoryWindows) { + auto node = GetWindowNode(id); + if (node != nullptr) { + DestroyWindowInner(node); + } + } + WLOGFI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId); } -void WindowRoot::ProcessDisplayChange(const sptr& displayInfo, DisplayStateChangeType type) +void WindowRoot::ProcessDisplayChange(DisplayId displayId, DisplayStateChangeType type) { - DisplayId displayId = displayInfo->GetDisplayId(); ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); auto& displayIdVec = displayIdMap_[screenGroupId]; auto iter = windowNodeContainerMap_.find(screenGroupId); @@ -948,25 +991,11 @@ void WindowRoot::ProcessDisplayChange(const sptr& displayInfo, Disp auto container = iter->second; if (container == nullptr) { WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); + return; } - switch (type) { - case DisplayStateChangeType::SIZE_CHANGE: - case DisplayStateChangeType::UPDATE_ROTATION: { - WLOGFI("update display: %{public}" PRIu64", rotation: %{public}u", displayId, displayInfo->GetRotation()); - container->SetDisplayRotation(displayId, displayInfo->GetRotation()); - container->SetDisplaySize(displayId, displayInfo->GetWidth(), displayInfo->GetHeight()); - break; - } - case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { - WLOGFI("update display: %{public}" PRIu64" virtual pixel ratio", displayId); - container->SetDisplayVirtualPixelRatio(displayId, displayInfo->GetVirtualPixelRatio()); - break; - } - default: { - break; - } - } + auto displayInfoMap = GetAllDisplayInfos(displayIdVec); + container->GetMutiDisplayController()->ProcessDisplayChange(displayId, displayInfoMap, type); } float WindowRoot::GetVirtualPixelRatio(DisplayId displayId) const @@ -979,6 +1008,17 @@ float WindowRoot::GetVirtualPixelRatio(DisplayId displayId) const return container->GetDisplayVirtualPixelRatio(displayId); } +Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const +{ + Rect fulldisplayRect; + auto container = const_cast(this)->GetOrCreateWindowNodeContainer(displayId); + if (container == nullptr) { + WLOGFE("window container could not be found"); + return fulldisplayRect; + } + return container->GetDisplayGroupRect(); +} + WMError WindowRoot::GetAccessibilityWindowInfo(sptr& windowInfo) { for (auto iter = windowNodeContainerMap_.begin(); iter != windowNodeContainerMap_.end(); ++iter) { @@ -1009,17 +1049,6 @@ WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, return WMError::WM_OK; } -void WindowRoot::NotifyVirtualPixelRatioChange(sptr displayInfo) -{ - WLOGFD("window should be updated for virtual pixel ratio changed"); - auto container = GetOrCreateWindowNodeContainer(displayInfo->GetDisplayId()); - if (container == nullptr) { - WLOGFE("can't find window node container, failed!"); - return; - } - container->UpdateVirtualPixelRatio(displayInfo->GetDisplayId(), displayInfo->GetVirtualPixelRatio()); -} - void WindowRoot::SetWindowStretchable(bool stretchable) { WLOGFI("set window stretchable to %{publec}d", stretchable);