• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "display_group_controller.h"
16 
17 #include "window_inner_manager.h"
18 #include "window_manager_hilog.h"
19 #include "window_node_container.h"
20 
21 namespace OHOS {
22 namespace Rosen {
23 namespace {
24     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayGroupController"};
25 }
26 
InitNewDisplay(DisplayId displayId)27 void DisplayGroupController::InitNewDisplay(DisplayId displayId)
28 {
29     // system bar map for display
30     SysBarNodeMap sysBarNodeMap {
31         { WindowType::WINDOW_TYPE_STATUS_BAR,     nullptr },
32         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr },
33     };
34     sysBarNodeMaps_.insert(std::make_pair(displayId, sysBarNodeMap));
35 
36     SysBarTintMap sysBarTintMap {
37         { WindowType::WINDOW_TYPE_STATUS_BAR,     SystemBarRegionTint() },
38         { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() },
39     };
40     sysBarTintMaps_.insert(std::make_pair(displayId, sysBarTintMap));
41 
42     // window node maps for display
43     std::map<WindowRootNodeType, std::unique_ptr<std::vector<sptr<WindowNode>>>> displayWindowTree;
44     displayWindowTree.insert(std::make_pair(WindowRootNodeType::APP_WINDOW_NODE,
45         std::make_unique<std::vector<sptr<WindowNode>>>()));
46     displayWindowTree.insert(std::make_pair(WindowRootNodeType::ABOVE_WINDOW_NODE,
47         std::make_unique<std::vector<sptr<WindowNode>>>()));
48     displayWindowTree.insert(std::make_pair(WindowRootNodeType::BELOW_WINDOW_NODE,
49         std::make_unique<std::vector<sptr<WindowNode>>>()));
50     displayGroupWindowTree_.insert(std::make_pair(displayId, std::move(displayWindowTree)));
51 
52     // window pair for display
53     auto windowPair = new WindowPair(displayId);
54     windowPairMap_.insert(std::make_pair(displayId, windowPair));
55 }
56 
GetWindowNodesByDisplayIdAndRootType(DisplayId displayId,WindowRootNodeType type)57 std::vector<sptr<WindowNode>>* DisplayGroupController::GetWindowNodesByDisplayIdAndRootType(DisplayId displayId,
58                                                                                             WindowRootNodeType type)
59 {
60     if (displayGroupWindowTree_.find(displayId) != displayGroupWindowTree_.end()) {
61         auto& displayWindowTree = displayGroupWindowTree_[displayId];
62         if (displayWindowTree.find(type) != displayWindowTree.end()) {
63             return displayWindowTree[type].get();
64         }
65     }
66     return nullptr;
67 }
68 
AddWindowNodeOnWindowTree(sptr<WindowNode> & node,WindowRootNodeType rootType)69 void DisplayGroupController::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, WindowRootNodeType rootType)
70 {
71     std::vector<sptr<WindowNode>>* rootNodeVectorPtr = GetWindowNodesByDisplayIdAndRootType(node->GetDisplayId(),
72         rootType);
73     if (rootNodeVectorPtr != nullptr) {
74         rootNodeVectorPtr->push_back(node);
75         WLOGFD("add node in node vector of root, displayId: %{public}" PRIu64" windowId: %{public}d, "
76             "rootType: %{public}d", node->GetDisplayId(), node->GetWindowId(), rootType);
77     } else {
78         WLOGFE("add node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d",
79             node->GetWindowId(), rootType);
80     }
81 }
82 
UpdateDisplayGroupWindowTree()83 void DisplayGroupController::UpdateDisplayGroupWindowTree()
84 {
85     // clear ori window tree of displayGroup
86     for (auto& elem : displayGroupWindowTree_) {
87         for (auto& nodeVec : elem.second) {
88             auto emptyVector = std::vector<sptr<WindowNode>>();
89             nodeVec.second->swap(emptyVector);
90         }
91     }
92     std::vector<WindowRootNodeType> rootNodeType = {
93         WindowRootNodeType::ABOVE_WINDOW_NODE,
94         WindowRootNodeType::APP_WINDOW_NODE,
95         WindowRootNodeType::BELOW_WINDOW_NODE
96     };
97     for (auto& rootType : rootNodeType) {
98         auto rootNode = windowNodeContainer_->GetRootNode(rootType);
99         if (rootNode == nullptr) {
100             WLOGFE("rootNode is nullptr, %{public}d", rootType);
101             continue;
102         }
103         for (auto& node : rootNode->children_) {
104             AddWindowNodeOnWindowTree(node, rootType);
105         }
106     }
107 }
108 
ProcessCrossNodes(DisplayId defaultDisplayId,DisplayStateChangeType type)109 void DisplayGroupController::ProcessCrossNodes(DisplayId defaultDisplayId, DisplayStateChangeType type)
110 {
111     defaultDisplayId_ = defaultDisplayId;
112     for (auto& iter : displayGroupWindowTree_) {
113         auto nodeVec = *(iter.second[WindowRootNodeType::APP_WINDOW_NODE]);
114         for (auto node : nodeVec) {
115             if (node->isShowingOnMultiDisplays_) {
116                 WLOGFD("process cross node, windowId: %{public}u, displayId: %{public}" PRIu64"",
117                     node->GetWindowId(), node->GetDisplayId());
118                 auto showingDisplays = node->GetShowingDisplays();
119 
120                 DisplayId newDisplayId;
121                 if (type == DisplayStateChangeType::SIZE_CHANGE || type == DisplayStateChangeType::UPDATE_ROTATION ||
122                     type == DisplayStateChangeType::DISPLAY_COMPRESS) {
123                     newDisplayId = node->GetDisplayId();
124                 } else {
125                     newDisplayId = defaultDisplayId;
126                 }
127 
128                 for (auto& displayId : showingDisplays) {
129                     if (displayId == newDisplayId) {
130                         continue;
131                     }
132                     windowNodeContainer_->RemoveNodeFromRSTree(node, displayId, newDisplayId,
133                         WindowUpdateType::WINDOW_UPDATE_ACTIVE);
134                 }
135                 // update shown displays and displayId
136                 MoveCrossNodeToTargetDisplay(node, newDisplayId);
137             }
138         }
139     }
140 }
141 
UpdateWindowShowingDisplays(const sptr<WindowNode> & node)142 void DisplayGroupController::UpdateWindowShowingDisplays(const sptr<WindowNode>& node)
143 {
144     auto leftDisplayId = displayGroupInfo_->GetLeftDisplayId();
145     auto rightDisplayId = displayGroupInfo_->GetRightDisplayId();
146     auto displayRectMap = displayGroupInfo_->GetAllDisplayRects();
147     auto showingDisplays = std::vector<DisplayId>();
148     const auto& winRect = node->GetWindowRect();
149     for (auto& elem : displayRectMap) {
150         auto& curDisplayRect = elem.second;
151 
152         // if window is showing in display region
153         if (((winRect.posX_ + static_cast<int32_t>(winRect.width_)) > curDisplayRect.posX_) &&
154             (winRect.posX_ < (curDisplayRect.posX_ + static_cast<int32_t>(curDisplayRect.width_)))) {
155             showingDisplays.push_back(elem.first);
156         }
157     }
158 
159     // if window is not showing on any display, maybe in the left of minPosX display, or the right of maxPosX display
160     if (showingDisplays.empty()) {
161         if (((winRect.posX_ + static_cast<int32_t>(winRect.width_)) <=
162             displayRectMap[leftDisplayId].posX_)) {
163             showingDisplays.push_back(leftDisplayId);
164         }
165         if (winRect.posX_ >=
166             (displayRectMap[rightDisplayId].posX_ + static_cast<int32_t>(displayRectMap[rightDisplayId].width_))) {
167             showingDisplays.push_back(rightDisplayId);
168         }
169     }
170 
171     // mean that this is cross-display window
172     if (showingDisplays.size() > 1) {
173         node->isShowingOnMultiDisplays_ = true;
174     } else {
175         node->isShowingOnMultiDisplays_ = false;
176     }
177     node->SetShowingDisplays(showingDisplays);
178 }
179 
UpdateWindowDisplayIdIfNeeded(const sptr<WindowNode> & node)180 void DisplayGroupController::UpdateWindowDisplayIdIfNeeded(const sptr<WindowNode>& node)
181 {
182     // current multi-display is only support left-right combination, maxNum is two
183     DisplayId newDisplayId = node->GetDisplayId();
184     const auto& curShowingDisplays = node->GetShowingDisplays();
185     if (curShowingDisplays.empty()) {
186         WLOGFE("id:%{public}u not show on any display!", node->GetWindowId());
187         return;
188     }
189     const auto& winRect = node->GetWindowRect();
190     if (curShowingDisplays.size() == 1) {
191         newDisplayId = *(curShowingDisplays.begin());
192     } else {
193         // if more than half width of the window is showing on the display, means the window belongs to this display
194         int32_t halfWidth = static_cast<int32_t>(winRect.width_ * 0.5);
195         const auto& displayRectMap = displayGroupInfo_->GetAllDisplayRects();
196         for (auto& elem : displayRectMap) {
197             auto& displayRect = elem.second;
198             if ((winRect.posX_ < displayRect.posX_) &&
199                 (winRect.posX_ + static_cast<int32_t>(winRect.width_) >
200                 displayRect.posX_ + static_cast<int32_t>(displayRect.width_))) { // window covers whole display region
201                 newDisplayId = elem.first;
202                 break;
203             }
204             if (winRect.posX_ >= displayRect.posX_) { // current display is default display
205                 if ((displayRect.posX_ + static_cast<int32_t>(displayRect.width_) - winRect.posX_) >= halfWidth) {
206                     newDisplayId = elem.first;
207                     break;
208                 }
209             } else { // current display is expand display
210                 if ((winRect.posX_ + static_cast<int32_t>(winRect.width_) - displayRect.posX_) >= halfWidth) {
211                     newDisplayId = elem.first;
212                     break;
213                 }
214             }
215         }
216     }
217 
218     // update displayId if needed
219     if (node->GetDisplayId() != newDisplayId) {
220         UpdateWindowDisplayId(node, newDisplayId);
221         UpdateDisplayGroupWindowTree();
222     }
223 }
224 
ChangeToRectInDisplayGroup(const sptr<WindowNode> & node,DisplayId displayId)225 void DisplayGroupController::ChangeToRectInDisplayGroup(const sptr<WindowNode>& node, DisplayId displayId)
226 {
227     Rect requestRect = node->GetRequestRect();
228     const Rect& displayRect = displayGroupInfo_->GetDisplayRect(displayId);
229     requestRect.posX_ += displayRect.posX_;
230     requestRect.posY_ += displayRect.posY_;
231     node->SetRequestRect(requestRect);
232 
233     std::vector<DisplayId> curShowingDisplays = { node->GetDisplayId() };
234     node->SetShowingDisplays(curShowingDisplays);
235 }
236 
PreProcessWindowNode(const sptr<WindowNode> & node,WindowUpdateType type)237 void DisplayGroupController::PreProcessWindowNode(const sptr<WindowNode>& node, WindowUpdateType type)
238 {
239     if (!windowNodeContainer_->GetLayoutPolicy()->IsMultiDisplay()) {
240         if (type == WindowUpdateType::WINDOW_UPDATE_ADDED) {
241             std::vector<DisplayId> curShowingDisplays = { node->GetDisplayId() };
242             node->SetShowingDisplays(curShowingDisplays);
243             for (auto& childNode : node->children_) {
244                 PreProcessWindowNode(childNode, type);
245             }
246         }
247         WLOGFD("Current mode is not multi-display");
248         return;
249     }
250 
251     switch (type) {
252         case WindowUpdateType::WINDOW_UPDATE_ADDED: {
253             if (!node->isShowingOnMultiDisplays_) {
254                 // change rect to rect in display group
255                 ChangeToRectInDisplayGroup(node, node->GetDisplayId());
256             }
257             WLOGFD("preprocess node when add window");
258             break;
259         }
260         case WindowUpdateType::WINDOW_UPDATE_ACTIVE: {
261             // MoveTo can be called by user, calculate rect in display group if the reason is move
262             if (node->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) {
263                 ChangeToRectInDisplayGroup(node, defaultDisplayId_);
264             }
265             WLOGFD("preprocess node when update window");
266             break;
267         }
268         default:
269             break;
270     }
271 
272     for (auto& childNode : node->children_) {
273         PreProcessWindowNode(childNode, type);
274     }
275 }
276 
PostProcessWindowNode(const sptr<WindowNode> & node)277 void DisplayGroupController::PostProcessWindowNode(const sptr<WindowNode>& node)
278 {
279     if (!windowNodeContainer_->GetLayoutPolicy()->IsMultiDisplay()) {
280         WLOGFD("Current mode is not multi-display");
281         return;
282     }
283 
284     UpdateWindowShowingDisplays(node);
285     UpdateWindowDisplayIdIfNeeded(node);
286 }
287 
UpdateWindowDisplayId(const sptr<WindowNode> & node,DisplayId newDisplayId)288 void DisplayGroupController::UpdateWindowDisplayId(const sptr<WindowNode>& node, DisplayId newDisplayId)
289 {
290     WLOGFD("update node displayId, srcDisplayId: %{public}" PRIu64", newDisplayId: %{public}" PRIu64"",
291         node->GetDisplayId(), newDisplayId);
292     if (node->GetWindowToken()) {
293         node->GetWindowToken()->UpdateDisplayId(node->GetDisplayId(), newDisplayId);
294     }
295     node->SetDisplayId(newDisplayId);
296 }
297 
MoveCrossNodeToTargetDisplay(const sptr<WindowNode> & node,DisplayId targetDisplayId)298 void DisplayGroupController::MoveCrossNodeToTargetDisplay(const sptr<WindowNode>& node, DisplayId targetDisplayId)
299 {
300     node->isShowingOnMultiDisplays_ = false;
301     // update showing display
302     std::vector<DisplayId> newShowingDisplays = { targetDisplayId };
303     node->SetShowingDisplays(newShowingDisplays);
304     // update new displayId
305     if (node->GetDisplayId() != targetDisplayId) {
306         UpdateWindowDisplayId(node, targetDisplayId);
307     }
308 
309     for (auto& childNode : node->children_) {
310         MoveCrossNodeToTargetDisplay(childNode, targetDisplayId);
311     }
312 }
313 
MoveNotCrossNodeToDefaultDisplay(const sptr<WindowNode> & node,DisplayId displayId)314 void DisplayGroupController::MoveNotCrossNodeToDefaultDisplay(const sptr<WindowNode>& node, DisplayId displayId)
315 {
316     WLOGFD("windowId: %{public}d, displayId: %{public}" PRIu64"", node->GetWindowId(), displayId);
317     // update new rect in display group
318     const Rect& srcDisplayRect = displayGroupInfo_->GetDisplayRect(displayId);
319     const Rect& dstDisplayRect = displayGroupInfo_->GetDisplayRect(defaultDisplayId_);
320     Rect newRect = node->GetRequestRect();
321     if (node->GetWindowType() == WindowType::WINDOW_TYPE_POINTER) {
322         newRect.posX_ = static_cast<int32_t>(dstDisplayRect.width_ / 2); // default pointerX : displayRect.width / 2
323         newRect.posY_ = static_cast<int32_t>(dstDisplayRect.height_ / 2); // default pointerY : displayRect.height / 2
324     } else {
325         newRect.posX_ = newRect.posX_ - srcDisplayRect.posX_ + dstDisplayRect.posX_;
326         newRect.posY_ = newRect.posY_ - srcDisplayRect.posY_ + dstDisplayRect.posY_;
327     }
328 
329     node->SetRequestRect(newRect);
330     // update showing display
331     std::vector<DisplayId> newShowingDisplays = { defaultDisplayId_ };
332     node->SetShowingDisplays(newShowingDisplays);
333     // update new displayId
334     UpdateWindowDisplayId(node, defaultDisplayId_);
335 
336     for (auto& childNode : node->children_) {
337         MoveNotCrossNodeToDefaultDisplay(childNode, displayId);
338     }
339 }
340 
ProcessNotCrossNodesOnDestroyedDisplay(DisplayId displayId,std::vector<uint32_t> & windowIds)341 void DisplayGroupController::ProcessNotCrossNodesOnDestroyedDisplay(DisplayId displayId,
342                                                                     std::vector<uint32_t>& windowIds)
343 {
344     if (displayId == defaultDisplayId_) {
345         WLOGFE("Move window nodes failed, displayId is the same as defaultDisplayId");
346         return;
347     }
348     if (displayGroupWindowTree_.find(displayId) == displayGroupWindowTree_.end()) {
349         WLOGFE("displayId: %{public}" PRIu64" not in display group window tree", displayId);
350         return;
351     }
352     WLOGFI("move window nodes for display destroy, displayId: %{public}" PRIu64"", displayId);
353 
354     std::vector<WindowRootNodeType> rootNodeType = {
355         WindowRootNodeType::ABOVE_WINDOW_NODE,
356         WindowRootNodeType::APP_WINDOW_NODE,
357         WindowRootNodeType::BELOW_WINDOW_NODE
358     };
359     for (const auto& type : rootNodeType) {
360         if (displayGroupWindowTree_[displayId].find(type) == displayGroupWindowTree_[displayId].end()) {
361             continue;
362         }
363         auto nodesVec = *(displayGroupWindowTree_[displayId][type]);
364         for (auto node : nodesVec) {
365             WLOGFD("node on destroied display, windowId: %{public}d, isShowingOnMulti: %{public}d",
366                 node->GetWindowId(), node->isShowingOnMultiDisplays_);
367             if (node->GetDisplayId() != displayId || node->isShowingOnMultiDisplays_) {
368                 continue;
369             }
370             // destroy status and navigation bar
371             if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR ||
372                 node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
373                 windowNodeContainer_->DestroyWindowNode(node, windowIds);
374                 WLOGFW("destroy status or navigation bar on destroyed display, windowId: %{public}d",
375                     node->GetWindowId());
376                 continue;
377             }
378             // move not cross-display nodes to default display
379             MoveNotCrossNodeToDefaultDisplay(node, displayId);
380 
381             // update RS tree
382             windowNodeContainer_->RemoveNodeFromRSTree(node, displayId, defaultDisplayId_,
383                 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
384             windowNodeContainer_->AddNodeOnRSTree(node, defaultDisplayId_, defaultDisplayId_,
385                 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
386         }
387     }
388 }
389 
ProcessDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap)390 void DisplayGroupController::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
391                                                   const std::map<DisplayId, Rect>& displayRectMap)
392 {
393     WindowInnerManager::GetInstance().NotifyDisplayChange(displayRectMap);
394     defaultDisplayId_ = defaultDisplayId;
395     WLOGFI("defaultDisplay, displayId: %{public}" PRIu64"", defaultDisplayId);
396 
397     DisplayId displayId = displayInfo->GetDisplayId();
398 
399     InitNewDisplay(displayId);
400 
401     // add displayInfo in displayGroupInfo
402     displayGroupInfo_->AddDisplayInfo(displayInfo);
403 
404     // modify RSTree and window tree of displayGroup for cross-display nodes
405     ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::CREATE);
406     UpdateDisplayGroupWindowTree();
407     const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy();
408     layoutPolicy->ProcessDisplayCreate(displayId, displayRectMap);
409     Rect initialDividerRect = layoutPolicy->GetDividerRect(displayId);
410     SetDividerRect(displayId, initialDividerRect);
411 }
412 
ProcessDisplayDestroy(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap,std::vector<uint32_t> & windowIds)413 void DisplayGroupController::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
414                                                    const std::map<DisplayId, Rect>& displayRectMap,
415                                                    std::vector<uint32_t>& windowIds)
416 {
417     WindowInnerManager::GetInstance().NotifyDisplayChange(displayRectMap);
418     DisplayId displayId = displayInfo->GetDisplayId();
419 
420     // delete nodes and map element of deleted display
421     ProcessNotCrossNodesOnDestroyedDisplay(displayId, windowIds);
422     // modify RSTree and window tree of displayGroup for cross-display nodes
423     ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::DESTROY);
424     UpdateDisplayGroupWindowTree();
425     ClearMapOfDestroyedDisplay(displayId);
426     windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayDestroy(displayId, displayRectMap);
427 }
428 
UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId)429 void DisplayGroupController::UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId)
430 {
431     std::vector<WindowRootNodeType> rootNodeType = {
432         WindowRootNodeType::ABOVE_WINDOW_NODE,
433         WindowRootNodeType::APP_WINDOW_NODE,
434         WindowRootNodeType::BELOW_WINDOW_NODE
435     };
436     for (auto& rootType : rootNodeType) {
437         std::vector<sptr<WindowNode>>* rootNodeVectorPtr = GetWindowNodesByDisplayIdAndRootType(displayId, rootType);
438         if (rootNodeVectorPtr == nullptr) {
439             WLOGFE("rootNodeVectorPtr is nullptr, %{public}d, displayId: %{public}" PRIu64, rootType, displayId);
440             return;
441         }
442         for (auto& node : (*rootNodeVectorPtr)) {
443             // DOCK_SLICE not need do rotation animation
444             if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
445                 continue;
446             }
447             node->SetWindowSizeChangeReason(WindowSizeChangeReason::ROTATION);
448         }
449     }
450 }
451 
ProcessDisplayChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,Rect> & displayRectMap,DisplayStateChangeType type)452 void DisplayGroupController::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
453                                                   const std::map<DisplayId, Rect>& displayRectMap,
454                                                   DisplayStateChangeType type)
455 {
456     WindowInnerManager::GetInstance().NotifyDisplayChange(displayRectMap);
457     DisplayId displayId = displayInfo->GetDisplayId();
458     WLOGFI("display change, displayId: %{public}" PRIu64", type: %{public}d", displayId, type);
459     switch (type) {
460         case DisplayStateChangeType::UPDATE_ROTATION: {
461             displayGroupInfo_->SetDisplayRotation(displayId, displayInfo->GetRotation());
462             [[fallthrough]];
463         }
464         case DisplayStateChangeType::DISPLAY_COMPRESS:
465         case DisplayStateChangeType::SIZE_CHANGE: {
466             ProcessDisplaySizeChangeOrRotation(defaultDisplayId, displayId, displayRectMap, type);
467             break;
468         }
469         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
470             displayGroupInfo_->SetDisplayVirtualPixelRatio(displayId, displayInfo->GetVirtualPixelRatio());
471             windowNodeContainer_->GetLayoutPolicy()->LayoutWindowTree(displayId);
472             break;
473         }
474         default: {
475             break;
476         }
477     }
478 }
479 
ProcessDisplaySizeChangeOrRotation(DisplayId defaultDisplayId,DisplayId displayId,const std::map<DisplayId,Rect> & displayRectMap,DisplayStateChangeType type)480 void DisplayGroupController::ProcessDisplaySizeChangeOrRotation(DisplayId defaultDisplayId, DisplayId displayId,
481     const std::map<DisplayId, Rect>& displayRectMap, DisplayStateChangeType type)
482 {
483     // modify RSTree and window tree of displayGroup for cross-display nodes
484     ProcessCrossNodes(defaultDisplayId, type);
485     UpdateDisplayGroupWindowTree();
486     const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy();
487     if (layoutPolicy == nullptr) {
488         return;
489     }
490     // update reason after process cross Nodes to get correct display attribution
491     UpdateNodeSizeChangeReasonWithRotation(displayId);
492     layoutPolicy->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap);
493     Rect curDividerRect = layoutPolicy->GetDividerRect(displayId);
494     if (windowPairMap_[displayId] != nullptr) {
495         windowPairMap_[displayId]->RotateDividerWindow(curDividerRect);
496     }
497 }
498 
ClearMapOfDestroyedDisplay(DisplayId displayId)499 void DisplayGroupController::ClearMapOfDestroyedDisplay(DisplayId displayId)
500 {
501     sysBarTintMaps_.erase(displayId);
502     sysBarNodeMaps_.erase(displayId);
503     displayGroupWindowTree_.erase(displayId);
504     displayGroupInfo_->RemoveDisplayInfo(displayId);
505     windowPairMap_.erase(displayId);
506 }
507 
GetWindowPairByDisplayId(DisplayId displayId)508 sptr<WindowPair> DisplayGroupController::GetWindowPairByDisplayId(DisplayId displayId)
509 {
510     if (windowPairMap_.find(displayId) != windowPairMap_.end()) {
511         return windowPairMap_[displayId];
512     }
513     return nullptr;
514 }
515 
SetDividerRect(DisplayId displayId,const Rect & rect)516 void DisplayGroupController::SetDividerRect(DisplayId displayId, const Rect& rect)
517 {
518     if (windowPairMap_.find(displayId) != windowPairMap_.end()) {
519         windowPairMap_[displayId]->SetDividerRect(rect);
520     }
521 }
522 } // namespace Rosen
523 } // namespace OHOS
524