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