1 /*
2 * Copyright (c) 2021-2023 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
16 #include "window_root.h"
17 #include <ability_manager_client.h>
18 #include <cinttypes>
19 #include <display_power_mgr_client.h>
20 #include <hisysevent.h>
21 #include <hitrace_meter.h>
22 #include <transaction/rs_transaction.h>
23
24 #include "display_manager_service_inner.h"
25 #include "permission.h"
26 #include "window_helper.h"
27 #include "window_inner_manager.h"
28 #include "window_manager_hilog.h"
29 #include "window_manager_service.h"
30 #include "window_manager_service_utils.h"
31 #include "window_manager_agent_controller.h"
32 #include "window_system_effect.h"
33 #ifdef MEMMGR_WINDOW_ENABLE
34 #include "mem_mgr_client.h"
35 #include "mem_mgr_window_info.h"
36 #endif
37 namespace OHOS {
38 namespace Rosen {
39 namespace {
40 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Root"};
41 }
42
GetTotalWindowNum() const43 uint32_t WindowRoot::GetTotalWindowNum() const
44 {
45 return static_cast<uint32_t>(windowNodeMap_.size());
46 }
47
GetWindowForDumpAceHelpInfo() const48 sptr<WindowNode> WindowRoot::GetWindowForDumpAceHelpInfo() const
49 {
50 for (auto& iter : windowNodeMap_) {
51 if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP ||
52 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
53 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR ||
54 iter.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
55 return iter.second;
56 }
57 }
58 return nullptr;
59 }
60
GetScreenGroupId(DisplayId displayId,bool & isRecordedDisplay)61 ScreenId WindowRoot::GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay)
62 {
63 for (auto iter : displayIdMap_) {
64 auto displayIdVec = iter.second;
65 if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) {
66 isRecordedDisplay = true;
67 return iter.first;
68 }
69 }
70 isRecordedDisplay = false;
71 WLOGFE("Current display is not be recorded, displayId: %{public}" PRIu64 "", displayId);
72 return DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId);
73 }
74
GetOrCreateWindowNodeContainer(DisplayId displayId)75 sptr<WindowNodeContainer> WindowRoot::GetOrCreateWindowNodeContainer(DisplayId displayId)
76 {
77 auto container = GetWindowNodeContainer(displayId);
78 if (container != nullptr) {
79 return container;
80 }
81
82 // In case of have no container for default display, create container
83 WLOGI("Create container for current display, displayId: %{public}" PRIu64 "", displayId);
84 sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId);
85 DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
86 return CreateWindowNodeContainer(defaultDisplayId, displayInfo);
87 }
88
GetWindowNodeContainer(DisplayId displayId)89 sptr<WindowNodeContainer> WindowRoot::GetWindowNodeContainer(DisplayId displayId)
90 {
91 bool isRecordedDisplay;
92 ScreenId displayGroupId = GetScreenGroupId(displayId, isRecordedDisplay);
93 auto iter = windowNodeContainerMap_.find(displayGroupId);
94 if (iter != windowNodeContainerMap_.end()) {
95 // if container exist for screenGroup and display is not be recorded, process expand display
96 if (!isRecordedDisplay) {
97 sptr<DisplayInfo> displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId);
98 // add displayId in displayId vector
99 displayIdMap_[displayGroupId].push_back(displayId);
100 auto displayRectMap = GetAllDisplayRectsByDMS(displayInfo);
101 DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
102 ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap);
103 }
104 return iter->second;
105 }
106 return nullptr;
107 }
108
CreateWindowNodeContainer(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo)109 sptr<WindowNodeContainer> WindowRoot::CreateWindowNodeContainer(DisplayId defaultDisplayId,
110 sptr<DisplayInfo> displayInfo)
111 {
112 if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) {
113 WLOGFE("get display failed or get invalid display info");
114 return nullptr;
115 }
116
117 DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId);
118 DisplayId displayId = displayInfo->GetDisplayId();
119 ScreenId displayGroupId = displayInfo->GetScreenGroupId();
120 WLOGI("create new container for display, width: %{public}d, height: %{public}d, "
121 "displayGroupId:%{public}" PRIu64", displayId:%{public}" PRIu64"", displayInfo->GetWidth(),
122 displayInfo->GetHeight(), displayGroupId, displayId);
123 sptr<WindowNodeContainer> container = new WindowNodeContainer(displayInfo, displayGroupId);
124 windowNodeContainerMap_.insert(std::make_pair(displayGroupId, container));
125 std::vector<DisplayId> displayVec = { displayId };
126 displayIdMap_.insert(std::make_pair(displayGroupId, displayVec));
127 if (container == nullptr) {
128 WLOGFE("create container failed, displayId :%{public}" PRIu64 "", displayId);
129 return nullptr;
130 }
131 container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_);
132 return container;
133 }
134
CheckDisplayInfo(const sptr<DisplayInfo> & display)135 bool WindowRoot::CheckDisplayInfo(const sptr<DisplayInfo>& display)
136 {
137 const int32_t minWidth = 50;
138 const int32_t minHeight = 50;
139 const int32_t maxWidth = 7680;
140 const int32_t maxHeight = 7680; // 8k resolution
141 if (display->GetWidth() < minWidth || display->GetWidth() > maxWidth ||
142 display->GetHeight() < minHeight || display->GetHeight() > maxHeight) {
143 return false;
144 }
145 return true;
146 }
147
GetWindowNode(uint32_t windowId) const148 sptr<WindowNode> WindowRoot::GetWindowNode(uint32_t windowId) const
149 {
150 auto iter = windowNodeMap_.find(windowId);
151 if (iter == windowNodeMap_.end()) {
152 return nullptr;
153 }
154 return iter->second;
155 }
156
GetWindowNodeByMissionId(uint32_t missionId) const157 sptr<WindowNode> WindowRoot::GetWindowNodeByMissionId(uint32_t missionId) const
158 {
159 using ValueType = const std::map<uint32_t, sptr<WindowNode>>::value_type&;
160 auto it = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(), [missionId] (ValueType item) {
161 return item.second && item.second->abilityInfo_.missionId_ == static_cast<int32_t>(missionId);
162 });
163 return it == windowNodeMap_.end() ? nullptr : it->second;
164 }
165
GetBackgroundNodesByScreenId(ScreenId screenGroupId,std::vector<sptr<WindowNode>> & windowNodes)166 void WindowRoot::GetBackgroundNodesByScreenId(ScreenId screenGroupId, std::vector<sptr<WindowNode>>& windowNodes)
167 {
168 for (const auto& it : windowNodeMap_) {
169 if (it.second == nullptr) {
170 continue;
171 }
172 wptr<WindowNodeContainer> container = GetWindowNodeContainer(it.second->GetDisplayId());
173 if (container == nullptr) {
174 continue;
175 }
176 auto iter = std::find_if(windowNodeContainerMap_.begin(), windowNodeContainerMap_.end(),
177 [container](const std::map<uint64_t, sptr<WindowNodeContainer>>::value_type& containerPair) {
178 return container.promote() == containerPair.second;
179 });
180 ScreenId screenGroupIdOfNode = INVALID_SCREEN_ID;
181 if (iter != windowNodeContainerMap_.end()) {
182 screenGroupIdOfNode = iter->first;
183 }
184 if (screenGroupId == screenGroupIdOfNode && !it.second->currentVisibility_) {
185 windowNodes.push_back(it.second);
186 }
187 }
188 }
189
FindWindowNodeWithToken(const sptr<IRemoteObject> & token) const190 sptr<WindowNode> WindowRoot::FindWindowNodeWithToken(const sptr<IRemoteObject>& token) const
191 {
192 if (token == nullptr) {
193 WLOGFE("token is null");
194 return nullptr;
195 }
196 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(),
197 [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) {
198 if ((WindowHelper::IsMainWindow(pair.second->GetWindowType())) ||
199 (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP)) {
200 return pair.second->abilityToken_ == token;
201 }
202 return false;
203 });
204 if (iter == windowNodeMap_.end()) {
205 WLOGE("cannot find windowNode");
206 return nullptr;
207 }
208 return iter->second;
209 }
210
AddDeathRecipient(sptr<WindowNode> node)211 void WindowRoot::AddDeathRecipient(sptr<WindowNode> node)
212 {
213 if (node == nullptr || node->GetWindowToken() == nullptr) {
214 WLOGFE("failed, node is nullptr");
215 return;
216 }
217 WLOGFD("Add for window: %{public}u", node->GetWindowId());
218
219 auto remoteObject = node->GetWindowToken()->AsObject();
220 windowIdMap_.insert(std::make_pair(remoteObject, node->GetWindowId()));
221
222 if (windowDeath_ == nullptr) {
223 WLOGE("failed to create death Recipient ptr WindowDeathRecipient");
224 return;
225 }
226 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
227 WLOGE("failed to add death recipient");
228 }
229 }
230
SaveWindow(const sptr<WindowNode> & node)231 WMError WindowRoot::SaveWindow(const sptr<WindowNode>& node)
232 {
233 if (node == nullptr) {
234 WLOGFE("add window failed, node is nullptr");
235 return WMError::WM_ERROR_NULLPTR;
236 }
237
238 WLOGFD("save windowId %{public}u", node->GetWindowId());
239 windowNodeMap_.insert(std::make_pair(node->GetWindowId(), node));
240 if (node->surfaceNode_ != nullptr) {
241 surfaceIdWindowNodeMap_.insert(std::make_pair(node->surfaceNode_->GetId(), node));
242 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
243 // Register FirstFrame Callback to rs, inform ability to get snapshot
244 wptr<WindowNode> weak = node;
245 auto firstFrameCompleteCallback = [weak]() {
246 auto weakNode = weak.promote();
247 if (weakNode == nullptr) {
248 WLOGFE("windowNode is nullptr");
249 return;
250 }
251 WindowInnerManager::GetInstance().CompleteFirstFrameDrawing(weakNode);
252 };
253 node->surfaceNode_->SetBufferAvailableCallback(firstFrameCompleteCallback);
254 }
255 }
256 AddDeathRecipient(node);
257 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
258 WindowInfoReporter::GetInstance().InsertCreateReportInfo(node->abilityInfo_.bundleName_);
259 }
260 return WMError::WM_OK;
261 }
262
MinimizeStructuredAppWindowsExceptSelf(sptr<WindowNode> & node)263 WMError WindowRoot::MinimizeStructuredAppWindowsExceptSelf(sptr<WindowNode>& node)
264 {
265 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "root:MinimizeStructuredAppWindowsExceptSelf");
266 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
267 if (container == nullptr) {
268 WLOGFE("MinimizeAbility failed, window container could not be found");
269 return WMError::WM_ERROR_NULLPTR;
270 }
271 return container->MinimizeStructuredAppWindowsExceptSelf(node);
272 }
273
MinimizeTargetWindows(std::vector<uint32_t> & windowIds)274 void WindowRoot::MinimizeTargetWindows(std::vector<uint32_t>& windowIds)
275 {
276 for (auto& windowId : windowIds) {
277 if (windowNodeMap_.count(windowId) != 0) {
278 auto windowNode = windowNodeMap_[windowId];
279 if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
280 MinimizeApp::AddNeedMinimizeApp(windowNode, MinimizeReason::GESTURE_ANIMATION);
281 } else {
282 WLOGFE("Minimize window failed id: %{public}u, type: %{public}u",
283 windowNode->GetWindowId(), static_cast<uint32_t>(windowNode->GetWindowType()));
284 }
285 } else {
286 WLOGFW("Cannot find window with id: %{public}u", windowId);
287 }
288 }
289 }
290
GetSplitScreenWindowNodes(DisplayId displayId)291 std::vector<sptr<WindowNode>> WindowRoot::GetSplitScreenWindowNodes(DisplayId displayId)
292 {
293 auto container = GetOrCreateWindowNodeContainer(displayId);
294 if (container == nullptr) {
295 return {};
296 }
297 auto displayGroupController = container->GetDisplayGroupController();
298 if (displayGroupController == nullptr) {
299 return {};
300 }
301 auto windowPair = displayGroupController->GetWindowPairByDisplayId(displayId);
302 if (windowPair == nullptr) {
303 return {};
304 }
305 return windowPair->GetPairedWindows();
306 }
307
IsForbidDockSliceMove(DisplayId displayId) const308 bool WindowRoot::IsForbidDockSliceMove(DisplayId displayId) const
309 {
310 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId);
311 if (container == nullptr) {
312 WLOGFE("can't find container");
313 return true;
314 }
315 return container->IsForbidDockSliceMove(displayId);
316 }
317
IsDockSliceInExitSplitModeArea(DisplayId displayId) const318 bool WindowRoot::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
319 {
320 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId);
321 if (container == nullptr) {
322 WLOGFE("can't find container");
323 return false;
324 }
325 return container->IsDockSliceInExitSplitModeArea(displayId);
326 }
327
ExitSplitMode(DisplayId displayId)328 void WindowRoot::ExitSplitMode(DisplayId displayId)
329 {
330 auto container = GetOrCreateWindowNodeContainer(displayId);
331 if (container == nullptr) {
332 WLOGFE("can't find container");
333 return;
334 }
335 container->ExitSplitMode(displayId);
336 }
337
AddSurfaceNodeIdWindowNodePair(uint64_t surfaceNodeId,sptr<WindowNode> node)338 void WindowRoot::AddSurfaceNodeIdWindowNodePair(uint64_t surfaceNodeId, sptr<WindowNode> node)
339 {
340 surfaceIdWindowNodeMap_.insert(std::make_pair(surfaceNodeId, node));
341 }
342
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos) const343 void WindowRoot::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos) const
344 {
345 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
346 WLOGFE("Get Visible Window Permission Denied");
347 }
348 VisibleData& VisibleWindow = lastOcclusionData_->GetVisibleData();
349 for (auto surfaceId : VisibleWindow) {
350 auto iter = surfaceIdWindowNodeMap_.find(surfaceId);
351 if (iter == surfaceIdWindowNodeMap_.end()) {
352 continue;
353 }
354 sptr<WindowNode> node = iter->second;
355 if (node == nullptr) {
356 continue;
357 }
358 infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
359 node->GetCallingUid(), true, node->GetWindowType()));
360 }
361 }
362
GetWindowVisibilityChangeInfo(std::shared_ptr<RSOcclusionData> occlusionData)363 std::vector<std::pair<uint64_t, bool>> WindowRoot::GetWindowVisibilityChangeInfo(
364 std::shared_ptr<RSOcclusionData> occlusionData)
365 {
366 std::vector<std::pair<uint64_t, bool>> visibilityChangeInfo;
367 VisibleData& currentVisibleWindow = occlusionData->GetVisibleData();
368 std::sort(currentVisibleWindow.begin(), currentVisibleWindow.end());
369 VisibleData& lastVisibleWindow = lastOcclusionData_->GetVisibleData();
370 uint32_t i, j;
371 i = j = 0;
372 for (; i < lastVisibleWindow.size() && j < currentVisibleWindow.size();) {
373 if (lastVisibleWindow[i] < currentVisibleWindow[j]) {
374 visibilityChangeInfo.emplace_back(lastVisibleWindow[i], false);
375 i++;
376 } else if (lastVisibleWindow[i] > currentVisibleWindow[j]) {
377 visibilityChangeInfo.emplace_back(currentVisibleWindow[j], true);
378 j++;
379 } else {
380 i++;
381 j++;
382 }
383 }
384 for (; i < lastVisibleWindow.size(); ++i) {
385 visibilityChangeInfo.emplace_back(lastVisibleWindow[i], false);
386 }
387 for (; j < currentVisibleWindow.size(); ++j) {
388 visibilityChangeInfo.emplace_back(currentVisibleWindow[j], true);
389 }
390 lastOcclusionData_ = occlusionData;
391 return visibilityChangeInfo;
392 }
393
NotifyWindowVisibilityChange(std::shared_ptr<RSOcclusionData> occlusionData)394 void WindowRoot::NotifyWindowVisibilityChange(std::shared_ptr<RSOcclusionData> occlusionData)
395 {
396 std::vector<std::pair<uint64_t, bool>> visibilityChangeInfo = GetWindowVisibilityChangeInfo(occlusionData);
397 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
398 #ifdef MEMMGR_WINDOW_ENABLE
399 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
400 #endif
401 for (const auto& elem : visibilityChangeInfo) {
402 uint64_t surfaceId = elem.first;
403 bool isVisible = elem.second;
404 auto iter = surfaceIdWindowNodeMap_.find(surfaceId);
405 if (iter == surfaceIdWindowNodeMap_.end()) {
406 continue;
407 }
408 sptr<WindowNode> node = iter->second;
409 if (node == nullptr) {
410 continue;
411 }
412 node->isVisible_ = isVisible;
413 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
414 node->GetCallingUid(), isVisible, node->GetWindowType()));
415 #ifdef MEMMGR_WINDOW_ENABLE
416 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(node->GetWindowId(), node->GetCallingPid(),
417 node->GetCallingUid(), isVisible));
418 #endif
419 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
420 node->GetWindowId(), isVisible);
421 }
422 CheckAndNotifyWaterMarkChangedResult();
423 if (windowVisibilityInfos.size() != 0) {
424 WLOGI("Notify windowvisibilityinfo changed start");
425 WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
426 }
427 #ifdef MEMMGR_WINDOW_ENABLE
428 if (memMgrWindowInfos.size() != 0) {
429 WLOGI("Notify memMgrWindowInfos changed start");
430 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
431 }
432 #endif
433 }
434
GetAvoidAreaByType(uint32_t windowId,AvoidAreaType avoidAreaType)435 AvoidArea WindowRoot::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType)
436 {
437 AvoidArea avoidArea;
438 sptr<WindowNode> node = GetWindowNode(windowId);
439 if (node == nullptr) {
440 WLOGFE("could not find window");
441 return avoidArea;
442 }
443 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
444 if (container == nullptr) {
445 WLOGFE("add window failed, window container could not be found");
446 return avoidArea;
447 }
448 return container->GetAvoidAreaByType(node, avoidAreaType);
449 }
450
MinimizeAllAppWindows(DisplayId displayId)451 void WindowRoot::MinimizeAllAppWindows(DisplayId displayId)
452 {
453 auto container = GetOrCreateWindowNodeContainer(displayId);
454 if (container == nullptr) {
455 WLOGFE("can't find window node container, failed!");
456 return;
457 }
458 return container->MinimizeAllAppWindows(displayId);
459 }
460
ToggleShownStateForAllAppWindows()461 WMError WindowRoot::ToggleShownStateForAllAppWindows()
462 {
463 std::vector<DisplayId> displays = DisplayGroupInfo::GetInstance().GetAllDisplayIds();
464 std::vector<sptr<WindowNodeContainer>> containers;
465 bool isAllAppWindowsEmpty = true;
466 for (auto displayId : displays) {
467 auto container = GetOrCreateWindowNodeContainer(displayId);
468 if (container == nullptr) {
469 WLOGFE("can't find window node container, failed!");
470 continue;
471 }
472 containers.emplace_back(container);
473 isAllAppWindowsEmpty = isAllAppWindowsEmpty && container->IsAppWindowsEmpty();
474 }
475 WMError res = WMError::WM_OK;
476 std::for_each(containers.begin(), containers.end(),
477 [this, isAllAppWindowsEmpty, &res] (sptr<WindowNodeContainer> container) {
478 auto restoreFunc = [this](uint32_t windowId, WindowMode mode) {
479 auto windowNode = GetWindowNode(windowId);
480 if (windowNode == nullptr) {
481 return false;
482 }
483 if (!windowNode->GetWindowToken()) {
484 return false;
485 }
486 auto property = windowNode->GetWindowToken()->GetWindowProperty();
487 if (property == nullptr) {
488 return false;
489 }
490 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
491 mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
492 property->SetWindowMode(mode);
493 // when change mode, need to reset shadow and radius
494 windowNode->SetWindowMode(mode);
495 WindowSystemEffect::SetWindowEffect(windowNode);
496 windowNode->GetWindowToken()->RestoreSplitWindowMode(static_cast<uint32_t>(mode));
497 }
498 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_SHOWN);
499 WindowManagerService::GetInstance().AddWindow(property);
500 return true;
501 };
502 WMError tmpRes = container->ToggleShownStateForAllAppWindows(restoreFunc, isAllAppWindowsEmpty);
503 res = (res == WMError::WM_OK) ? tmpRes : res;
504 });
505 return res;
506 }
507
DestroyLeakStartingWindow()508 void WindowRoot::DestroyLeakStartingWindow()
509 {
510 WLOGFD("DestroyLeakStartingWindow is called");
511 std::vector<uint32_t> destroyIds;
512 for (auto& iter : windowNodeMap_) {
513 if (iter.second->startingWindowShown_ && !iter.second->GetWindowToken()) {
514 destroyIds.push_back(iter.second->GetWindowId());
515 }
516 }
517 for (auto& id : destroyIds) {
518 WLOGFD("Id:%{public}u", id);
519 DestroyWindow(id, false);
520 }
521 }
522
PostProcessAddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode,sptr<WindowNodeContainer> & container)523 WMError WindowRoot::PostProcessAddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode,
524 sptr<WindowNodeContainer>& container)
525 {
526 if (!node->currentVisibility_) {
527 WLOGW("window is invisible, do not need process");
528 return WMError::WM_DO_NOTHING;
529 }
530 if (WindowHelper::IsSubWindow(node->GetWindowType())) {
531 if (parentNode == nullptr) {
532 WLOGFE("window type is invalid");
533 return WMError::WM_ERROR_INVALID_TYPE;
534 }
535 sptr<WindowNode> parent = nullptr;
536 container->RaiseZOrderForAppWindow(parentNode, parent);
537 }
538 if (node->GetWindowProperty()->GetFocusable()) {
539 // when launcher reboot, the focus window should not change with showing a full screen window.
540 sptr<WindowNode> focusWin = GetWindowNode(container->GetFocusWindow());
541 if (focusWin == nullptr ||
542 !(WindowHelper::IsFullScreenWindow(focusWin->GetWindowMode()) && focusWin->zOrder_ > node->zOrder_)) {
543 container->SetFocusWindow(node->GetWindowId());
544 needCheckFocusWindow = true;
545 }
546 }
547 if (!WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
548 container->SetActiveWindow(node->GetWindowId(), false);
549 }
550
551 for (auto& child : node->children_) {
552 if (child == nullptr || !child->currentVisibility_) {
553 break;
554 }
555 HandleKeepScreenOn(child->GetWindowId(), child->IsKeepScreenOn());
556 }
557 HandleKeepScreenOn(node->GetWindowId(), node->IsKeepScreenOn());
558 WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d",
559 node->GetWindowId(), node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()),
560 node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType()));
561 if (WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
562 if (node->stateMachine_.IsShowAnimationPlaying()) {
563 WLOGFD("[FixOrientation] window is playing show animation, do not update display orientation");
564 return WMError::WM_OK;
565 }
566 auto topRotatableWindow = container->GetNextRotatableWindow(INVALID_WINDOW_ID);
567 if (topRotatableWindow == node) {
568 container->SetDisplayOrientationFromWindow(node, true);
569 }
570 }
571 return WMError::WM_OK;
572 }
573
CheckAddingModeAndSize(sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container)574 bool WindowRoot::CheckAddingModeAndSize(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container)
575 {
576 if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
577 return true;
578 }
579 // intercept the node which doesn't support floating mode at tile mode
580 if (WindowHelper::IsInvalidWindowInTileLayoutMode(node->GetModeSupportInfo(), container->GetCurrentLayoutMode())) {
581 WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId());
582 return false;
583 }
584 // intercept the node that the tile rect can't be applied to
585 WMError res = container->IsTileRectSatisfiedWithSizeLimits(node);
586 if (res != WMError::WM_OK) {
587 return false;
588 }
589 return true;
590 }
591
GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode)592 Rect WindowRoot::GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode)
593 {
594 DisplayId displayId = dstNode->GetDisplayId();
595 std::map<WindowType, std::pair<bool, Rect>> systemBarRects;
596 for (const auto& it : windowNodeMap_) {
597 auto& node = it.second;
598 if (node && (node->GetDisplayId() == displayId) &&
599 WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
600 systemBarRects[node->GetWindowType()] = std::make_pair(node->currentVisibility_, node->GetWindowRect());
601 }
602 }
603 auto container = GetOrCreateWindowNodeContainer(displayId);
604 if (container == nullptr) {
605 WLOGFE("failed, window container could not be found");
606 return {0, 0, 0, 0}; // empty rect
607 }
608 auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
609 Rect targetRect = displayRect;
610 auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(displayId);
611 if (displayInfo && WmsUtils::IsExpectedRotatableWindow(dstNode->GetRequestedOrientation(),
612 displayInfo->GetDisplayOrientation(), dstNode->GetWindowMode(), dstNode->GetWindowFlags())) {
613 WLOGFD("[FixOrientation] the window is expected rotatable, pre-calculated");
614 targetRect.height_ = displayRect.width_;
615 targetRect.width_ = displayRect.height_;
616 return targetRect;
617 }
618
619 bool isStatusShow = true;
620 if (systemBarRects.count(WindowType::WINDOW_TYPE_STATUS_BAR)) {
621 isStatusShow = systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].first;
622 targetRect.posY_ = displayRect.posY_ + static_cast<int32_t>(
623 systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_);
624 targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_;
625 WLOGFD("after status bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
626 targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_);
627 }
628 if (systemBarRects.count(WindowType::WINDOW_TYPE_NAVIGATION_BAR)) {
629 if (isStatusShow && !(systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].first)) {
630 return targetRect;
631 }
632 targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].second.height_;
633 WLOGFD("after navi bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
634 targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_);
635 }
636 return targetRect;
637 }
638
GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>> & windowNodes)639 void WindowRoot::GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>>& windowNodes)
640 {
641 for (const auto& it : windowNodeMap_) {
642 if (it.second) {
643 if (!WindowHelper::IsMainWindow(it.second->GetWindowType())) {
644 continue;
645 }
646 WLOGFD("id:%{public}u state:%{public}u",
647 it.second->GetWindowId(), static_cast<uint32_t>(it.second->stateMachine_.GetCurrentState()));
648 if (it.second->stateMachine_.IsRemoteAnimationPlaying() ||
649 it.second->stateMachine_.GetAnimationCount() > 0) {
650 windowNodes.emplace_back(it.second);
651 }
652 }
653 }
654 }
655
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)656 void WindowRoot::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
657 {
658 if (node == nullptr) {
659 WLOGFE("failed, node is nullptr");
660 return;
661 }
662 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
663 if (container == nullptr) {
664 WLOGFE("add window failed, window container could not be found");
665 return;
666 }
667
668 if (!CheckAddingModeAndSize(node, container)) { // true means stop adding
669 WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId());
670 return;
671 }
672
673 container->LayoutWhenAddWindowNode(node, afterAnimation);
674 return;
675 }
676
BindDialogToParent(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)677 WMError WindowRoot::BindDialogToParent(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
678 {
679 if (node->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
680 return WMError::WM_OK;
681 }
682 sptr<WindowNode> callerNode = FindMainWindowWithToken(node->dialogTargetToken_);
683 parentNode = (callerNode != nullptr) ? callerNode : nullptr;
684 if (parentNode == nullptr) {
685 node->GetWindowToken()->NotifyDestroy();
686 return WMError::WM_ERROR_INVALID_PARAM;
687 }
688 return WMError::WM_OK;
689 }
690
AddWindowNode(uint32_t parentId,sptr<WindowNode> & node,bool fromStartingWin)691 WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr<WindowNode>& node, bool fromStartingWin)
692 {
693 if (node == nullptr) {
694 return WMError::WM_ERROR_NULLPTR;
695 }
696
697 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
698 if (container == nullptr) {
699 return WMError::WM_ERROR_INVALID_DISPLAY;
700 }
701
702 if (!CheckAddingModeAndSize(node, container)) { // true means stop adding
703 /*
704 * Starting Window has no windowToken, which should be destroied if mode or size is invalid
705 */
706 if (node->GetWindowToken() == nullptr) {
707 (void)DestroyWindow(node->GetWindowId(), false);
708 }
709 WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId());
710 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
711 }
712
713 if (fromStartingWin) {
714 if (WindowHelper::IsFullScreenWindow(node->GetWindowMode()) &&
715 WindowHelper::IsAppWindow(node->GetWindowType()) && !node->isPlayAnimationShow_) {
716 WMError res = MinimizeStructuredAppWindowsExceptSelf(node);
717 if (res != WMError::WM_OK) {
718 WLOGFE("Minimize other structured window failed");
719 MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
720 return res;
721 }
722 }
723 WMError res = container->ShowStartingWindow(node);
724 if (res != WMError::WM_OK) {
725 MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
726 }
727 return res;
728 }
729 if (WindowHelper::IsAppFullOrSplitWindow(node->GetWindowType(), node->GetWindowMode())) {
730 container->NotifyDockWindowStateChanged(node, false);
731 }
732 // limit number of main window
733 uint32_t mainWindowNumber = container->GetWindowCountByType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
734 if (mainWindowNumber >= maxAppWindowNumber_ && node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
735 container->MinimizeOldestAppWindow();
736 }
737
738 auto parentNode = GetWindowNode(parentId);
739
740 WMError res = BindDialogToParent(node, parentNode);
741 if (res != WMError::WM_OK) {
742 return res;
743 }
744
745 res = container->AddWindowNode(node, parentNode);
746 if (res != WMError::WM_OK) {
747 WLOGFE("failed with ret: %{public}u", static_cast<uint32_t>(res));
748 return res;
749 }
750 return PostProcessAddWindowNode(node, parentNode, container);
751 }
752
RemoveWindowNode(uint32_t windowId,bool fromAnimation)753 WMError WindowRoot::RemoveWindowNode(uint32_t windowId, bool fromAnimation)
754 {
755 WLOGFD("begin");
756 auto node = GetWindowNode(windowId);
757 if (node == nullptr) {
758 WLOGFE("could not find window");
759 return WMError::WM_ERROR_NULLPTR;
760 }
761 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
762 if (container == nullptr) {
763 WLOGFE("failed, window container could not be found");
764 return WMError::WM_ERROR_INVALID_DISPLAY;
765 }
766 container->DropShowWhenLockedWindowIfNeeded(node);
767 UpdateFocusWindowWithWindowRemoved(node, container);
768 UpdateActiveWindowWithWindowRemoved(node, container);
769 UpdateBrightnessWithWindowRemoved(windowId, container);
770 WMError res = container->RemoveWindowNode(node, fromAnimation);
771 if (res == WMError::WM_OK) {
772 for (auto& child : node->children_) {
773 if (child == nullptr) {
774 break;
775 }
776 HandleKeepScreenOn(child->GetWindowId(), false);
777 }
778 HandleKeepScreenOn(windowId, false);
779 }
780 return res;
781 }
782
UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode> & node)783 void WindowRoot::UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode>& node)
784 {
785 if (!FIX_ORIENTATION_ENABLE) {
786 return;
787 }
788 WLOGFD("[FixOrientation] begin");
789 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
790 if (container == nullptr) {
791 WLOGFE("[FixOrientation] failed, window container could not be found");
792 return;
793 }
794 auto nextRotatableWindow = container->GetNextRotatableWindow(node->GetWindowId());
795 if (nextRotatableWindow != nullptr) {
796 WLOGFD("[FixOrientation] next rotatable window: %{public}u", nextRotatableWindow->GetWindowId());
797 container->SetDisplayOrientationFromWindow(nextRotatableWindow, false);
798 }
799 }
800
SetGestureNavigaionEnabled(bool enable)801 WMError WindowRoot::SetGestureNavigaionEnabled(bool enable)
802 {
803 if (lastGestureNativeEnabled_ == enable) {
804 WLOGFW("Do not set gesture navigation too much times as same value and the value is %{public}d", enable);
805 return WMError::WM_DO_NOTHING;
806 }
807 WindowManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
808 lastGestureNativeEnabled_ = enable;
809 WLOGFD("Set gesture navigation enabled succeeded and notify result of %{public}d", enable);
810 return WMError::WM_OK;
811 }
812
UpdateWindowNode(uint32_t windowId,WindowUpdateReason reason)813 WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason)
814 {
815 auto node = GetWindowNode(windowId);
816 if (node == nullptr) {
817 WLOGFE("could not find window");
818 return WMError::WM_ERROR_NULLPTR;
819 }
820 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
821 if (container == nullptr) {
822 WLOGFE("update window failed, window container could not be found");
823 return WMError::WM_ERROR_INVALID_DISPLAY;
824 }
825
826 auto ret = container->UpdateWindowNode(node, reason);
827 if (ret == WMError::WM_OK && reason == WindowUpdateReason::UPDATE_FLAGS) {
828 CheckAndNotifyWaterMarkChangedResult();
829 }
830 return ret;
831 }
832
UpdateSizeChangeReason(uint32_t windowId,WindowSizeChangeReason reason)833 WMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason)
834 {
835 auto node = GetWindowNode(windowId);
836 if (node == nullptr) {
837 WLOGFE("could not find window");
838 return WMError::WM_ERROR_NULLPTR;
839 }
840 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
841 if (container == nullptr) {
842 WLOGFE("failed, window container could not be found");
843 return WMError::WM_ERROR_INVALID_DISPLAY;
844 }
845 container->UpdateSizeChangeReason(node, reason);
846 return WMError::WM_OK;
847 }
848
SetBrightness(uint32_t windowId,float brightness)849 void WindowRoot::SetBrightness(uint32_t windowId, float brightness)
850 {
851 auto node = GetWindowNode(windowId);
852 if (node == nullptr) {
853 WLOGFE("could not find window");
854 return;
855 }
856 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
857 if (container == nullptr) {
858 WLOGFE("failed, window container could not be found");
859 return;
860 }
861 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
862 WLOGW("Only app window support set brightness");
863 return;
864 }
865 if (windowId == container->GetActiveWindow()) {
866 if (container->GetDisplayBrightness() != brightness) {
867 WLOGFI("value: %{public}u", container->ToOverrideBrightness(brightness));
868 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
869 container->ToOverrideBrightness(brightness));
870 container->SetDisplayBrightness(brightness);
871 }
872 container->SetBrightnessWindow(windowId);
873 }
874 }
875
HandleKeepScreenOn(uint32_t windowId,bool requireLock)876 void WindowRoot::HandleKeepScreenOn(uint32_t windowId, bool requireLock)
877 {
878 auto node = GetWindowNode(windowId);
879 if (node == nullptr) {
880 WLOGFE("could not find window");
881 return;
882 }
883 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
884 if (container == nullptr) {
885 WLOGFE("failed, window container could not be found");
886 return;
887 }
888 container->HandleKeepScreenOn(node, requireLock);
889 }
890
UpdateFocusableProperty(uint32_t windowId)891 void WindowRoot::UpdateFocusableProperty(uint32_t windowId)
892 {
893 auto node = GetWindowNode(windowId);
894 if (node == nullptr) {
895 WLOGFE("could not find window");
896 return;
897 }
898 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
899 if (container == nullptr) {
900 WLOGFE("failed, window container could not be found");
901 return;
902 }
903
904 if (windowId != container->GetFocusWindow() || node->GetWindowProperty()->GetFocusable()) {
905 return;
906 }
907 auto nextFocusableWindow = container->GetNextFocusableWindow(windowId);
908 if (nextFocusableWindow != nullptr) {
909 WLOGI("Next focus window id: %{public}u", nextFocusableWindow->GetWindowId());
910 container->SetFocusWindow(nextFocusableWindow->GetWindowId());
911 }
912 }
913
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)914 WMError WindowRoot::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
915 {
916 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
917 if (container == nullptr) {
918 WLOGFE("failed, window container could not be found");
919 return WMError::WM_ERROR_INVALID_DISPLAY;
920 }
921 WindowMode curWinMode = node->GetWindowMode();
922 if (curWinMode == dstMode) {
923 return WMError::WM_OK;
924 }
925 auto res = container->SetWindowMode(node, dstMode);
926 auto nextRotatableWindow = container->GetNextRotatableWindow(0);
927 if (nextRotatableWindow != nullptr) {
928 DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(nextRotatableWindow->GetDisplayId(),
929 nextRotatableWindow->GetRequestedOrientation());
930 }
931 return res;
932 }
933
DestroyWindowSelf(sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container)934 WMError WindowRoot::DestroyWindowSelf(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container)
935 {
936 for (auto& child : node->children_) {
937 if (child == nullptr) {
938 continue;
939 }
940 child->parent_ = nullptr;
941 if ((child->GetWindowToken() != nullptr) && (child->abilityToken_ != node->abilityToken_) &&
942 (child->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
943 child->GetWindowToken()->NotifyDestroy();
944 }
945 }
946 std::vector<uint32_t> windowIds;
947 WMError res = container->DestroyWindowNode(node, windowIds);
948 if (res != WMError::WM_OK) {
949 WLOGFE("RemoveWindowNode failed");
950 }
951 return DestroyWindowInner(node);
952 }
953
DestroyWindowWithChild(sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container)954 WMError WindowRoot::DestroyWindowWithChild(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container)
955 {
956 auto token = node->abilityToken_;
957 std::vector<uint32_t> windowIds;
958 WMError res = container->DestroyWindowNode(node, windowIds);
959 for (auto id : windowIds) {
960 node = GetWindowNode(id);
961 if (!node) {
962 continue;
963 }
964 HandleKeepScreenOn(id, false);
965 DestroyWindowInner(node);
966 if ((node->GetWindowToken() != nullptr) && (node->abilityToken_ != token) &&
967 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
968 node->GetWindowToken()->NotifyDestroy();
969 }
970 }
971 return res;
972 }
973
DestroyWindow(uint32_t windowId,bool onlySelf)974 WMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf)
975 {
976 auto node = GetWindowNode(windowId);
977 if (node == nullptr) {
978 WLOGFE("failed, because window node is not exist.");
979 return WMError::WM_ERROR_NULLPTR;
980 }
981 WLOGI("windowId %{public}u, onlySelf:%{public}u.", windowId, onlySelf);
982 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
983 if (!container) {
984 WLOGFW("failed, window container could not be found");
985 return DestroyWindowInner(node);
986 }
987
988 UpdateFocusWindowWithWindowRemoved(node, container);
989 UpdateActiveWindowWithWindowRemoved(node, container);
990 UpdateBrightnessWithWindowRemoved(windowId, container);
991 HandleKeepScreenOn(windowId, false);
992 if (onlySelf) {
993 return DestroyWindowSelf(node, container);
994 } else {
995 return DestroyWindowWithChild(node, container);
996 }
997 }
998
DestroyWindowInner(sptr<WindowNode> & node)999 WMError WindowRoot::DestroyWindowInner(sptr<WindowNode>& node)
1000 {
1001 if (node == nullptr) {
1002 WLOGFE("window has been destroyed");
1003 return WMError::WM_ERROR_DESTROYED_OBJECT;
1004 }
1005
1006 if (node->isVisible_) {
1007 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
1008 node->isVisible_ = false;
1009 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
1010 node->GetCallingUid(), false, node->GetWindowType()));
1011 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
1012 node->GetWindowId(), node->isVisible_);
1013 WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
1014
1015 CheckAndNotifyWaterMarkChangedResult();
1016 }
1017
1018 auto cmpFunc = [node](const std::map<uint64_t, sptr<WindowNode>>::value_type& pair) {
1019 if (pair.second == nullptr) {
1020 return false;
1021 }
1022 if (pair.second->GetWindowId() == node->GetWindowId()) {
1023 return true;
1024 }
1025 return false;
1026 };
1027 auto iter = std::find_if(surfaceIdWindowNodeMap_.begin(), surfaceIdWindowNodeMap_.end(), cmpFunc);
1028 if (iter != surfaceIdWindowNodeMap_.end()) {
1029 surfaceIdWindowNodeMap_.erase(iter);
1030 }
1031
1032 sptr<IWindow> window = node->GetWindowToken();
1033 if ((window != nullptr) && (window->AsObject() != nullptr)) {
1034 if (windowIdMap_.count(window->AsObject()) == 0) {
1035 WLOGE("window remote object has been destroyed");
1036 return WMError::WM_ERROR_DESTROYED_OBJECT;
1037 }
1038
1039 if (window->AsObject() != nullptr) {
1040 window->AsObject()->RemoveDeathRecipient(windowDeath_);
1041 }
1042 windowIdMap_.erase(window->AsObject());
1043 }
1044 windowNodeMap_.erase(node->GetWindowId());
1045 WLOGI("destroy window use_count:%{public}d", node->GetSptrRefCount());
1046 return WMError::WM_OK;
1047 }
1048
UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container) const1049 void WindowRoot::UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode>& node,
1050 const sptr<WindowNodeContainer>& container) const
1051 {
1052 if (node == nullptr || container == nullptr) {
1053 WLOGFE("window is invalid");
1054 return;
1055 }
1056 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1057 WLOGI("window is divider, do not get next focus window.");
1058 return;
1059 }
1060 uint32_t windowId = node->GetWindowId();
1061 uint32_t focusedWindowId = container->GetFocusWindow();
1062 WLOGFD("current window: %{public}u, focus window: %{public}u", windowId, focusedWindowId);
1063 if (windowId != focusedWindowId) {
1064 auto iter = std::find_if(node->children_.begin(), node->children_.end(),
1065 [focusedWindowId](sptr<WindowNode> node) {
1066 return node->GetWindowId() == focusedWindowId;
1067 });
1068 if (iter == node->children_.end()) {
1069 return;
1070 }
1071 }
1072 if (!node->children_.empty()) {
1073 auto firstChild = node->children_.front();
1074 if (firstChild->priority_ < 0) {
1075 windowId = firstChild->GetWindowId();
1076 }
1077 }
1078
1079 auto nextFocusableWindow = container->GetNextFocusableWindow(windowId);
1080 if (nextFocusableWindow != nullptr) {
1081 WLOGFD("adjust focus window, next focus window id: %{public}u", nextFocusableWindow->GetWindowId());
1082 container->SetFocusWindow(nextFocusableWindow->GetWindowId());
1083 }
1084 }
1085
UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container) const1086 void WindowRoot::UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode>& node,
1087 const sptr<WindowNodeContainer>& container) const
1088 {
1089 if (node == nullptr || container == nullptr) {
1090 WLOGFE("window is invalid");
1091 return;
1092 }
1093 uint32_t windowId = node->GetWindowId();
1094 uint32_t activeWindowId = container->GetActiveWindow();
1095 WLOGFD("current window: %{public}u, active window: %{public}u", windowId, activeWindowId);
1096 if (windowId != activeWindowId) {
1097 auto iter = std::find_if(node->children_.begin(), node->children_.end(),
1098 [activeWindowId](sptr<WindowNode> node) {
1099 return node->GetWindowId() == activeWindowId;
1100 });
1101 if (iter == node->children_.end()) {
1102 return;
1103 }
1104 }
1105 if (!node->children_.empty()) {
1106 auto firstChild = node->children_.front();
1107 if (firstChild->priority_ < 0) {
1108 windowId = firstChild->GetWindowId();
1109 }
1110 }
1111
1112 auto nextActiveWindow = container->GetNextActiveWindow(windowId);
1113 if (nextActiveWindow != nullptr) {
1114 WLOGI("Next active window id: %{public}u", nextActiveWindow->GetWindowId());
1115 container->SetActiveWindow(nextActiveWindow->GetWindowId(), true);
1116 }
1117 }
1118
UpdateBrightnessWithWindowRemoved(uint32_t windowId,const sptr<WindowNodeContainer> & container) const1119 void WindowRoot::UpdateBrightnessWithWindowRemoved(uint32_t windowId, const sptr<WindowNodeContainer>& container) const
1120 {
1121 if (container == nullptr) {
1122 WLOGFE("window container could not be found");
1123 return;
1124 }
1125 if (windowId == container->GetBrightnessWindow()) {
1126 WLOGFD("winId: %{public}u", container->GetActiveWindow());
1127 container->UpdateBrightness(container->GetActiveWindow(), true);
1128 }
1129 }
1130
IsVerticalDisplay(sptr<WindowNode> & node) const1131 bool WindowRoot::IsVerticalDisplay(sptr<WindowNode>& node) const
1132 {
1133 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1134 if (container == nullptr) {
1135 WLOGFE("get display direction failed, window container could not be found");
1136 return false;
1137 }
1138 return container->IsVerticalDisplay(node->GetDisplayId());
1139 }
1140
RequestFocus(uint32_t windowId)1141 WMError WindowRoot::RequestFocus(uint32_t windowId)
1142 {
1143 auto node = GetWindowNode(windowId);
1144 if (node == nullptr) {
1145 WLOGFE("could not find window");
1146 return WMError::WM_ERROR_NULLPTR;
1147 }
1148 if (!node->currentVisibility_) {
1149 WLOGFE("could not request focus before it does not be shown");
1150 return WMError::WM_ERROR_INVALID_OPERATION;
1151 }
1152 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1153 if (container == nullptr) {
1154 WLOGFE("window container could not be found");
1155 return WMError::WM_ERROR_NULLPTR;
1156 }
1157 if (node->GetWindowProperty()->GetFocusable()) {
1158 return container->SetFocusWindow(windowId);
1159 }
1160 return WMError::WM_ERROR_INVALID_OPERATION;
1161 }
1162
RequestActiveWindow(uint32_t windowId)1163 WMError WindowRoot::RequestActiveWindow(uint32_t windowId)
1164 {
1165 auto node = GetWindowNode(windowId);
1166 if (node == nullptr) {
1167 WLOGFE("could not find window");
1168 return WMError::WM_ERROR_NULLPTR;
1169 }
1170 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1171 WLOGFE("window could not be active window");
1172 return WMError::WM_ERROR_INVALID_TYPE;
1173 }
1174 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1175 if (container == nullptr) {
1176 WLOGFE("window container could not be found");
1177 return WMError::WM_ERROR_NULLPTR;
1178 }
1179 auto res = container->SetActiveWindow(windowId, false);
1180 WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d",
1181 windowId, node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()),
1182 node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType()));
1183 return res;
1184 }
1185
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1186 void WindowRoot::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1187 {
1188 for (auto& elem : windowNodeContainerMap_) {
1189 if (elem.second == nullptr) {
1190 continue;
1191 }
1192 elem.second->ProcessWindowStateChange(state, reason);
1193 }
1194 }
1195
NotifySystemBarTints()1196 void WindowRoot::NotifySystemBarTints()
1197 {
1198 WLOGFD("notify current system bar tints");
1199 for (auto& it : windowNodeContainerMap_) {
1200 if (it.second != nullptr) {
1201 it.second->NotifySystemBarTints(displayIdMap_[it.first]);
1202 }
1203 }
1204 }
1205
NotifyDesktopUnfrozen()1206 WMError WindowRoot::NotifyDesktopUnfrozen()
1207 {
1208 WLOGFD("notify desktop unfrozen");
1209 for (const auto& it : windowNodeMap_) {
1210 auto& node = it.second;
1211 // just need notify desktop unfrozen when desktop shown
1212 // since unfrozen will change window state to shown
1213 if (node && (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP)
1214 && (node->GetWindowToken()) && node->currentVisibility_) {
1215 node->GetWindowToken()->UpdateWindowState(WindowState::STATE_UNFROZEN);
1216 return WMError::WM_OK;
1217 }
1218 }
1219 WLOGFD("notify desktop unfrozen failed, maybe no window node or windowToken!");
1220 return WMError::WM_ERROR_INVALID_OPERATION;
1221 }
1222
FindWallpaperWindow()1223 sptr<WindowNode> WindowRoot::FindWallpaperWindow()
1224 {
1225 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(),
1226 [](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) {
1227 return pair.second->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER;
1228 });
1229 if (iter == windowNodeMap_.end()) {
1230 WLOGI("cannot find windowNode");
1231 return nullptr;
1232 }
1233 return iter->second;
1234 }
1235
RaiseZOrderForAppWindow(sptr<WindowNode> & node)1236 WMError WindowRoot::RaiseZOrderForAppWindow(sptr<WindowNode>& node)
1237 {
1238 if (node == nullptr) {
1239 WLOGFW("add window failed, node is nullptr");
1240 return WMError::WM_ERROR_NULLPTR;
1241 }
1242 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1243 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1244 if (container == nullptr) {
1245 WLOGFW("window container could not be found");
1246 return WMError::WM_ERROR_NULLPTR;
1247 }
1248 container->RaiseSplitRelatedWindowToTop(node);
1249 return WMError::WM_OK;
1250 }
1251 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1252 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1253 if (container == nullptr) {
1254 WLOGFW("window container could not be found");
1255 return WMError::WM_ERROR_NULLPTR;
1256 }
1257 sptr<WindowNode> parentNode = FindMainWindowWithToken(node->dialogTargetToken_);
1258 if (parentNode != nullptr) {
1259 container->RaiseZOrderForAppWindow(node, parentNode);
1260 }
1261 return WMError::WM_OK;
1262 }
1263
1264 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
1265 WLOGFW("window is not app window");
1266 return WMError::WM_ERROR_INVALID_TYPE;
1267 }
1268 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1269 if (container == nullptr) {
1270 WLOGFW("add window failed, window container could not be found");
1271 return WMError::WM_ERROR_NULLPTR;
1272 }
1273
1274 auto parentNode = GetWindowNode(node->GetParentId());
1275 return container->RaiseZOrderForAppWindow(node, parentNode);
1276 }
1277
DispatchKeyEvent(sptr<WindowNode> node,std::shared_ptr<MMI::KeyEvent> event)1278 void WindowRoot::DispatchKeyEvent(sptr<WindowNode> node, std::shared_ptr<MMI::KeyEvent> event)
1279 {
1280 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1281 if (container == nullptr) {
1282 WLOGFW("window container could not be found");
1283 return;
1284 }
1285 std::vector<sptr<WindowNode>> windowNodes;
1286 container->TraverseContainer(windowNodes);
1287 auto iter = std::find(windowNodes.begin(), windowNodes.end(), node);
1288 if (iter == windowNodes.end()) {
1289 WLOGFE("Cannot find node");
1290 return;
1291 }
1292 for (++iter; iter != windowNodes.end(); ++iter) {
1293 if (*iter == nullptr) {
1294 WLOGFE("Node is null");
1295 continue;
1296 }
1297 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
1298 WLOGFI("Skip component window: %{public}u", (*iter)->GetWindowId());
1299 continue;
1300 }
1301 if (WindowHelper::IsAppWindow((*iter)->GetWindowType())) {
1302 WLOGFI("App window: %{public}u", (*iter)->GetWindowId());
1303 if ((*iter)->GetWindowToken()) {
1304 (*iter)->GetWindowToken()->ConsumeKeyEvent(event);
1305 }
1306 break;
1307 }
1308 WLOGFI("Unexpected window: %{public}u", (*iter)->GetWindowId());
1309 break;
1310 }
1311 }
1312
GetWindowIdByObject(const sptr<IRemoteObject> & remoteObject)1313 uint32_t WindowRoot::GetWindowIdByObject(const sptr<IRemoteObject>& remoteObject)
1314 {
1315 auto iter = windowIdMap_.find(remoteObject);
1316 return iter == std::end(windowIdMap_) ? INVALID_WINDOW_ID : iter->second;
1317 }
1318
OnRemoteDied(const sptr<IRemoteObject> & remoteObject)1319 void WindowRoot::OnRemoteDied(const sptr<IRemoteObject>& remoteObject)
1320 {
1321 callback_(Event::REMOTE_DIED, remoteObject);
1322 }
1323
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)1324 WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
1325 {
1326 if (windowNodeMap_.find(mainWinId) == windowNodeMap_.end()) {
1327 return WMError::WM_ERROR_INVALID_WINDOW;
1328 }
1329 auto node = windowNodeMap_[mainWinId];
1330 if (!node->currentVisibility_) {
1331 return WMError::WM_ERROR_INVALID_WINDOW;
1332 }
1333 if (!node->children_.empty()) {
1334 auto iter = node->children_.rbegin();
1335 if (WindowHelper::IsSubWindow((*iter)->GetWindowType()) ||
1336 WindowHelper::IsSystemSubWindow((*iter)->GetWindowType())) {
1337 topWinId = (*iter)->GetWindowId();
1338 return WMError::WM_OK;
1339 }
1340 }
1341 topWinId = mainWinId;
1342 return WMError::WM_OK;
1343 }
1344
SetWindowLayoutMode(DisplayId displayId,WindowLayoutMode mode)1345 WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode)
1346 {
1347 auto container = GetOrCreateWindowNodeContainer(displayId);
1348 if (container == nullptr) {
1349 WLOGFE("window container could not be found");
1350 return WMError::WM_ERROR_NULLPTR;
1351 }
1352 WMError ret = container->SwitchLayoutPolicy(mode, displayId, true);
1353 if (ret != WMError::WM_OK) {
1354 WLOGFW("set window layout mode failed displayId: %{public}" PRIu64 ", ret: %{public}d", displayId, ret);
1355 }
1356 return ret;
1357 }
1358
GetAllDisplayIds() const1359 std::vector<DisplayId> WindowRoot::GetAllDisplayIds() const
1360 {
1361 std::vector<DisplayId> displayIds;
1362 for (auto& it : windowNodeContainerMap_) {
1363 if (!it.second) {
1364 return {};
1365 }
1366 std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[it.first];
1367 for (auto displayId : displayIdVec) {
1368 displayIds.push_back(displayId);
1369 }
1370 }
1371 return displayIds;
1372 }
1373
GenAllWindowsLogInfo() const1374 std::string WindowRoot::GenAllWindowsLogInfo() const
1375 {
1376 std::ostringstream os;
1377 WindowNodeOperationFunc func = [&os](sptr<WindowNode> node) {
1378 if (node == nullptr) {
1379 WLOGE("WindowNode is nullptr");
1380 return false;
1381 }
1382 os<<"window_name:"<<node->GetWindowName()<<",id:"<<node->GetWindowId()<<
1383 ",focusable:"<<node->GetWindowProperty()->GetFocusable()<<";";
1384 return false;
1385 };
1386
1387 for (auto& elem : windowNodeContainerMap_) {
1388 if (elem.second == nullptr) {
1389 continue;
1390 }
1391 std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[elem.first];
1392 for (const auto& displayId : displayIdVec) {
1393 os << "Display " << displayId << ":";
1394 }
1395 elem.second->TraverseWindowTree(func, true);
1396 }
1397 return os.str();
1398 }
1399
FocusFaultDetection() const1400 void WindowRoot::FocusFaultDetection() const
1401 {
1402 if (!needCheckFocusWindow) {
1403 return;
1404 }
1405 bool needReport = true;
1406 uint32_t focusWinId = INVALID_WINDOW_ID;
1407 for (auto& elem : windowNodeContainerMap_) {
1408 if (elem.second == nullptr) {
1409 continue;
1410 }
1411 focusWinId = elem.second->GetFocusWindow();
1412 if (focusWinId != INVALID_WINDOW_ID) {
1413 needReport = false;
1414 sptr<WindowNode> windowNode = GetWindowNode(focusWinId);
1415 if (windowNode == nullptr || !windowNode->currentVisibility_) {
1416 needReport = true;
1417 WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId);
1418 break;
1419 }
1420 }
1421 }
1422 if (needReport) {
1423 std::string windowLog(GenAllWindowsLogInfo());
1424 WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str());
1425 int32_t ret = HiSysEventWrite(
1426 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1427 "NO_FOCUS_WINDOW",
1428 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1429 "PID", getpid(),
1430 "UID", getuid(),
1431 "PACKAGE_NAME", "foundation",
1432 "PROCESS_NAME", "foundation",
1433 "MSG", windowLog);
1434 if (ret != 0) {
1435 WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
1436 }
1437 }
1438 }
1439
ProcessExpandDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,std::map<DisplayId,Rect> & displayRectMap)1440 void WindowRoot::ProcessExpandDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1441 std::map<DisplayId, Rect>& displayRectMap)
1442 {
1443 if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) {
1444 WLOGFE("get display failed or get invalid display info");
1445 return;
1446 }
1447 DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId);
1448 DisplayId displayId = displayInfo->GetDisplayId();
1449 ScreenId displayGroupId = displayInfo->GetScreenGroupId();
1450 auto container = windowNodeContainerMap_[displayGroupId];
1451 if (container == nullptr) {
1452 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1453 return;
1454 }
1455
1456 container->GetDisplayGroupController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap);
1457 container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_);
1458 WLOGI("Container exist, add new display, displayId: %{public}" PRIu64"", displayId);
1459 }
1460
GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo)1461 std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo)
1462 {
1463 std::map<DisplayId, Rect> displayRectMap;
1464
1465 if (displayInfo == nullptr) {
1466 return displayRectMap;
1467 }
1468
1469 for (auto& displayId : displayIdMap_[displayInfo->GetScreenGroupId()]) {
1470 auto info = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId);
1471 Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() };
1472 displayRectMap.insert(std::make_pair(displayId, displayRect));
1473
1474 WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]",
1475 displayId, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_);
1476 }
1477 return displayRectMap;
1478 }
1479
GetAllDisplayRectsByDisplayInfo(const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1480 std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDisplayInfo(
1481 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1482 {
1483 std::map<DisplayId, Rect> displayRectMap;
1484
1485 for (const auto& iter : displayInfoMap) {
1486 auto id = iter.first;
1487 auto info = iter.second;
1488 Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() };
1489 displayRectMap.insert(std::make_pair(id, displayRect));
1490
1491 WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]",
1492 id, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_);
1493 }
1494 return displayRectMap;
1495 }
1496
ProcessDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1497 void WindowRoot::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1498 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1499 {
1500 DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId();
1501 ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId();
1502 auto iter = windowNodeContainerMap_.find(displayGroupId);
1503 if (iter == windowNodeContainerMap_.end()) {
1504 CreateWindowNodeContainer(defaultDisplayId, displayInfo);
1505 WLOGI("Create new container for display, displayId: %{public}" PRIu64"", displayId);
1506 } else {
1507 auto& displayIdVec = displayIdMap_[displayGroupId];
1508 if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) {
1509 WLOGI("Current display is already exist, displayId: %{public}" PRIu64"", displayId);
1510 return;
1511 }
1512 // add displayId in displayId vector
1513 displayIdMap_[displayGroupId].push_back(displayId);
1514 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1515 ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap);
1516 }
1517 }
1518
MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId,DisplayId displayId)1519 void WindowRoot::MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId, DisplayId displayId)
1520 {
1521 for (auto& elem : windowNodeMap_) {
1522 auto& windowNode = elem.second;
1523 if (windowNode->GetDisplayId() == displayId && !windowNode->currentVisibility_) {
1524 std::vector<DisplayId> newShowingDisplays = { defaultDisplayId };
1525 windowNode->SetShowingDisplays(newShowingDisplays);
1526 windowNode->isShowingOnMultiDisplays_ = false;
1527 if (windowNode->GetWindowToken()) {
1528 windowNode->GetWindowToken()->UpdateDisplayId(windowNode->GetDisplayId(), defaultDisplayId);
1529 }
1530 windowNode->SetDisplayId(defaultDisplayId);
1531 }
1532 }
1533 }
1534
ProcessDisplayDestroy(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1535 void WindowRoot::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1536 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1537 {
1538 DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId();
1539 ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId();
1540 auto& displayIdVec = displayIdMap_[displayGroupId];
1541
1542 auto iter = windowNodeContainerMap_.find(displayGroupId);
1543 if (iter == windowNodeContainerMap_.end() ||
1544 std::find(displayIdVec.begin(), displayIdVec.end(), displayId) == displayIdVec.end() ||
1545 displayInfoMap.find(displayId) == displayInfoMap.end()) {
1546 WLOGFE("could not find display, destroy failed, displayId: %{public}" PRIu64"", displayId);
1547 return;
1548 }
1549
1550 // erase displayId in displayIdMap
1551 auto displayIter = std::remove(displayIdVec.begin(), displayIdVec.end(), displayId);
1552 displayIdVec.erase(displayIter, displayIdVec.end());
1553
1554 // container process display destroy
1555 auto container = iter->second;
1556 if (container == nullptr) {
1557 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1558 return;
1559 }
1560 WLOGI("displayId: %{public}" PRIu64"", displayId);
1561
1562 std::vector<uint32_t> needDestroyWindows;
1563 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1564 // erase displayId in displayRectMap
1565 auto displayRectIter = displayRectMap.find(displayId);
1566 if (displayRectIter == displayRectMap.end()) {
1567 return;
1568 }
1569 displayRectMap.erase(displayRectIter);
1570 container->GetDisplayGroupController()->ProcessDisplayDestroy(
1571 defaultDisplayId, displayInfo, displayRectMap, needDestroyWindows);
1572 for (auto id : needDestroyWindows) {
1573 auto node = GetWindowNode(id);
1574 if (node != nullptr) {
1575 DestroyWindowInner(node);
1576 }
1577 }
1578 // move window which is not showing on destroyed display to default display
1579 MoveNotShowingWindowToDefaultDisplay(defaultDisplayId, displayId);
1580 WLOGI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId);
1581 }
1582
ProcessDisplayChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)1583 void WindowRoot::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1584 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
1585 {
1586 if (displayInfo == nullptr) {
1587 WLOGFE("get display failed");
1588 return;
1589 }
1590 DisplayId displayId = displayInfo->GetDisplayId();
1591 ScreenId displayGroupId = displayInfo->GetScreenGroupId();
1592 auto& displayIdVec = displayIdMap_[displayGroupId];
1593 auto iter = windowNodeContainerMap_.find(displayGroupId);
1594 if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(),
1595 displayIdVec.end(), displayId) == displayIdVec.end()) {
1596 WLOGFE("[Display Change] could not find display, change failed, displayId: %{public}" PRIu64"", displayId);
1597 return;
1598 }
1599 // container process display change
1600 auto container = iter->second;
1601 if (container == nullptr) {
1602 WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1603 return;
1604 }
1605
1606 auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1607 container->GetDisplayGroupController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type);
1608 }
1609
GetDisplayGroupRect(DisplayId displayId) const1610 Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const
1611 {
1612 Rect fullDisplayRect;
1613 auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId);
1614 if (container == nullptr) {
1615 WLOGFE("window container could not be found");
1616 return fullDisplayRect;
1617 }
1618 return container->GetDisplayGroupRect();
1619 }
1620
HasPrivateWindow(DisplayId displayId)1621 bool WindowRoot::HasPrivateWindow(DisplayId displayId)
1622 {
1623 auto container = GetWindowNodeContainer(displayId);
1624 return container != nullptr ? container->HasPrivateWindow() : false;
1625 }
1626
HasMainFullScreenWindowShown(DisplayId displayId)1627 bool WindowRoot::HasMainFullScreenWindowShown(DisplayId displayId)
1628 {
1629 auto container = GetWindowNodeContainer(displayId);
1630 return container != nullptr ? container->HasMainFullScreenWindowShown() : false;
1631 }
1632
SetMaxAppWindowNumber(uint32_t windowNum)1633 void WindowRoot::SetMaxAppWindowNumber(uint32_t windowNum)
1634 {
1635 maxAppWindowNumber_ = windowNum;
1636 }
1637
SetSplitRatios(const std::vector<float> & splitRatioNumbers)1638 void WindowRoot::SetSplitRatios(const std::vector<float>& splitRatioNumbers)
1639 {
1640 auto& splitRatios = splitRatioConfig_.splitRatios;
1641 splitRatios.clear();
1642 splitRatios = splitRatioNumbers;
1643 for (auto iter = splitRatios.begin(); iter != splitRatios.end();) {
1644 if (*iter > 0 && *iter < 1) { // valid ratio range (0, 1)
1645 iter++;
1646 } else {
1647 iter = splitRatios.erase(iter);
1648 }
1649 }
1650 std::sort(splitRatios.begin(), splitRatios.end());
1651 auto iter = std::unique(splitRatios.begin(), splitRatios.end());
1652 splitRatios.erase(iter, splitRatios.end()); // remove duplicate ratios
1653 }
1654
SetExitSplitRatios(const std::vector<float> & exitSplitRatios)1655 void WindowRoot::SetExitSplitRatios(const std::vector<float>& exitSplitRatios)
1656 {
1657 if (exitSplitRatios.size() != 2) {
1658 return;
1659 }
1660 if (exitSplitRatios[0] > 0 && exitSplitRatios[0] < DEFAULT_SPLIT_RATIO) {
1661 splitRatioConfig_.exitSplitStartRatio = exitSplitRatios[0];
1662 }
1663 if (exitSplitRatios[1] > DEFAULT_SPLIT_RATIO && exitSplitRatios[1] < 1) {
1664 splitRatioConfig_.exitSplitEndRatio = exitSplitRatios[1];
1665 }
1666 }
1667
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)1668 WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId,
1669 ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config)
1670 {
1671 auto container = GetOrCreateWindowNodeContainer(displayId);
1672 if (container == nullptr) {
1673 WLOGFE("GetModeChangeHotZones failed, window container could not be found");
1674 return WMError::WM_ERROR_NULLPTR;
1675 }
1676 container->GetModeChangeHotZones(displayId, hotZones, config);
1677 return WMError::WM_OK;
1678 }
1679
RemoveSingleUserWindowNodes(int accountId)1680 void WindowRoot::RemoveSingleUserWindowNodes(int accountId)
1681 {
1682 std::vector<DisplayId> displayIds = GetAllDisplayIds();
1683 for (auto id : displayIds) {
1684 sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(id);
1685 if (container == nullptr) {
1686 WLOGW("get container failed %{public}" PRIu64"", id);
1687 continue;
1688 }
1689 container->RemoveSingleUserWindowNodes(accountId);
1690 }
1691 }
1692
UpdateRsTree(uint32_t windowId,bool isAdd)1693 WMError WindowRoot::UpdateRsTree(uint32_t windowId, bool isAdd)
1694 {
1695 sptr<WindowNode> node = GetWindowNode(windowId);
1696 if (node == nullptr) {
1697 WLOGFE("could not find window");
1698 return WMError::WM_ERROR_NULLPTR;
1699 }
1700 auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1701 if (container == nullptr) {
1702 WLOGFE("window container could not be found");
1703 return WMError::WM_ERROR_NULLPTR;
1704 }
1705 for (auto& displayId : node->GetShowingDisplays()) {
1706 if (isAdd) {
1707 container->AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
1708 } else {
1709 container->RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
1710 }
1711 }
1712 RSTransaction::FlushImplicitTransaction();
1713 return WMError::WM_OK;
1714 }
1715
FindMainWindowWithToken(sptr<IRemoteObject> token)1716 sptr<WindowNode> WindowRoot::FindMainWindowWithToken(sptr<IRemoteObject> token)
1717 {
1718 auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(),
1719 [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) {
1720 if (WindowHelper::IsMainWindow(pair.second->GetWindowType())) {
1721 return pair.second->abilityToken_ == token;
1722 }
1723 return false;
1724 });
1725 if (iter == windowNodeMap_.end()) {
1726 WLOGI("cannot find windowNode");
1727 return nullptr;
1728 }
1729 return iter->second;
1730 }
1731
CheckMultiDialogWindows(WindowType type,sptr<IRemoteObject> token)1732 bool WindowRoot::CheckMultiDialogWindows(WindowType type, sptr<IRemoteObject> token)
1733 {
1734 if (type != WindowType::WINDOW_TYPE_DIALOG) {
1735 return false;
1736 }
1737
1738 sptr<WindowNode> newCaller, oriCaller;
1739
1740 newCaller = FindMainWindowWithToken(token);
1741 if (newCaller == nullptr) {
1742 return false;
1743 }
1744
1745 for (auto& iter : windowNodeMap_) {
1746 if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1747 oriCaller = FindMainWindowWithToken(iter.second->dialogTargetToken_);
1748 if (oriCaller == newCaller) {
1749 return true;
1750 }
1751 }
1752 }
1753
1754 return false;
1755 }
1756
GetWindowNodeByAbilityToken(const sptr<IRemoteObject> & abilityToken)1757 sptr<WindowNode> WindowRoot::GetWindowNodeByAbilityToken(const sptr<IRemoteObject>& abilityToken)
1758 {
1759 for (const auto& iter : windowNodeMap_) {
1760 if (iter.second != nullptr && iter.second->abilityToken_ == abilityToken) {
1761 return iter.second;
1762 }
1763 }
1764 WLOGFE("could not find required abilityToken!");
1765 return nullptr;
1766 }
1767
TakeWindowPairSnapshot(DisplayId displayId)1768 bool WindowRoot::TakeWindowPairSnapshot(DisplayId displayId)
1769 {
1770 auto container = GetWindowNodeContainer(displayId);
1771 return container == nullptr ? false : container->TakeWindowPairSnapshot(displayId);
1772 }
1773
ClearWindowPairSnapshot(DisplayId displayId)1774 void WindowRoot::ClearWindowPairSnapshot(DisplayId displayId)
1775 {
1776 auto container = GetWindowNodeContainer(displayId);
1777 if (container == nullptr) {
1778 WLOGFE("clear window pair snapshot failed, because container in null");
1779 return;
1780 }
1781 return container->ClearWindowPairSnapshot(displayId);
1782 }
1783
CheckAndNotifyWaterMarkChangedResult()1784 void WindowRoot::CheckAndNotifyWaterMarkChangedResult()
1785 {
1786 auto searchWaterMarkWindow = [](wptr<WindowNode> node) {
1787 return (node != nullptr && node->isVisible_ &&
1788 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)));
1789 };
1790 bool currentWaterMarkState = false;
1791 for (auto& containerPair : windowNodeContainerMap_) {
1792 auto container = containerPair.second;
1793 if (container == nullptr) {
1794 continue;
1795 }
1796 std::vector<sptr<WindowNode>> allWindowNode;
1797 container->TraverseContainer(allWindowNode);
1798 auto itor = std::find_if(allWindowNode.begin(), allWindowNode.end(), searchWaterMarkWindow);
1799 if (itor != allWindowNode.end()) {
1800 currentWaterMarkState = true;
1801 break;
1802 }
1803 }
1804 if (lastWaterMarkShowStates_ != currentWaterMarkState) {
1805 WLOGFD("WaterMarkWindows has been changed. lastWaterMarkState : %{public}d, newState:%{public}d",
1806 lastWaterMarkShowStates_, currentWaterMarkState);
1807 WindowManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(currentWaterMarkState);
1808 lastWaterMarkShowStates_ = currentWaterMarkState;
1809 }
1810 }
1811 } // namespace Rosen
1812 } // namespace OHOS
1813