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