• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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