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->GetWindowModeSupportType(),
682         container->GetCurrentLayoutMode())) {
683         WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId());
684         return false;
685     }
686     // intercept the node that the tile rect can't be applied to
687     WMError res = container->IsTileRectSatisfiedWithSizeLimits(node);
688     if (res != WMError::WM_OK) {
689         return false;
690     }
691     return true;
692 }
693 
GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode)694 Rect WindowRoot::GetDisplayRectWithoutSystemBarAreas(const sptr<WindowNode> dstNode)
695 {
696     DisplayId displayId = dstNode->GetDisplayId();
697     std::map<WindowType, std::pair<bool, Rect>> systemBarRects;
698     for (const auto& it : windowNodeMap_) {
699         auto& node = it.second;
700         if (node && (node->GetDisplayId() == displayId) &&
701             WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
702             systemBarRects[node->GetWindowType()] = std::make_pair(node->currentVisibility_, node->GetWindowRect());
703         }
704     }
705     auto container = GetOrCreateWindowNodeContainer(displayId);
706     if (container == nullptr) {
707         WLOGFE("failed, window container could not be found");
708         return {0, 0, 0, 0}; // empty rect
709     }
710     auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
711     Rect targetRect = displayRect;
712     auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(displayId);
713     if (displayInfo && WmsUtils::IsExpectedRotatableWindow(dstNode->GetRequestedOrientation(),
714         displayInfo->GetDisplayOrientation(), dstNode->GetWindowMode(), dstNode->GetWindowFlags())) {
715         WLOGFD("[FixOrientation] the window is expected rotatable, pre-calculated");
716         targetRect.height_ = displayRect.width_;
717         targetRect.width_ = displayRect.height_;
718         return targetRect;
719     }
720 
721     bool isStatusShow = true;
722     if (systemBarRects.count(WindowType::WINDOW_TYPE_STATUS_BAR)) {
723         isStatusShow = systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].first;
724         targetRect.posY_ = displayRect.posY_ + static_cast<int32_t>(
725             systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_);
726         targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_STATUS_BAR].second.height_;
727         WLOGFD("after status bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
728             targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_);
729     }
730     if (systemBarRects.count(WindowType::WINDOW_TYPE_NAVIGATION_BAR)) {
731         if (isStatusShow && !(systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].first)) {
732             return targetRect;
733         }
734         targetRect.height_ -= systemBarRects[WindowType::WINDOW_TYPE_NAVIGATION_BAR].second.height_;
735         WLOGFD("after navi bar winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
736             targetRect.posX_, targetRect.posY_, targetRect.width_, targetRect.height_);
737     }
738     return targetRect;
739 }
740 
GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>> & windowNodes)741 void WindowRoot::GetAllAnimationPlayingNodes(std::vector<wptr<WindowNode>>& windowNodes)
742 {
743     for (const auto& it : windowNodeMap_) {
744         if (it.second) {
745             if (!WindowHelper::IsMainWindow(it.second->GetWindowType())) {
746                 continue;
747             }
748             WLOGFD("id:%{public}u state:%{public}u",
749                 it.second->GetWindowId(), static_cast<uint32_t>(it.second->stateMachine_.GetCurrentState()));
750             if (it.second->stateMachine_.IsRemoteAnimationPlaying() ||
751                 it.second->stateMachine_.GetAnimationCount() > 0) {
752                 windowNodes.emplace_back(it.second);
753             }
754         }
755     }
756 }
757 
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)758 void WindowRoot::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
759 {
760     if (node == nullptr) {
761         WLOGFE("failed, node is nullptr");
762         return;
763     }
764     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
765     if (container == nullptr) {
766         WLOGFE("add window failed, window container could not be found");
767         return;
768     }
769 
770     if (!CheckAddingModeAndSize(node, container)) { // true means stop adding
771         WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId());
772         return;
773     }
774 
775     container->LayoutWhenAddWindowNode(node, afterAnimation);
776     return;
777 }
778 
BindDialogToParent(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)779 WMError WindowRoot::BindDialogToParent(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
780 {
781     if (node->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
782         return WMError::WM_OK;
783     }
784     sptr<WindowNode> callerNode = FindMainWindowWithToken(node->dialogTargetToken_);
785     parentNode = (callerNode != nullptr) ? callerNode : nullptr;
786     if (parentNode == nullptr) {
787         node->GetWindowToken()->NotifyDestroy();
788         return WMError::WM_ERROR_INVALID_PARAM;
789     }
790     return WMError::WM_OK;
791 }
792 
AddWindowNode(uint32_t parentId,sptr<WindowNode> & node,bool fromStartingWin)793 WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr<WindowNode>& node, bool fromStartingWin)
794 {
795     if (node == nullptr) {
796         return WMError::WM_ERROR_NULLPTR;
797     }
798 
799     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
800     if (container == nullptr) {
801         return WMError::WM_ERROR_INVALID_DISPLAY;
802     }
803 
804     if (!CheckAddingModeAndSize(node, container)) { // true means stop adding
805         /*
806          * Starting Window has no windowToken, which should be destroied if mode or size is invalid
807          */
808         if (node->GetWindowToken() == nullptr) {
809             (void)DestroyWindow(node->GetWindowId(), false);
810         }
811         WLOGFE("Invalid mode or size in tile mode, windowId: %{public}u", node->GetWindowId());
812         return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
813     }
814 
815     if (fromStartingWin) {
816         if (WindowHelper::IsFullScreenWindow(node->GetWindowMode()) &&
817             WindowHelper::IsAppWindow(node->GetWindowType()) && !node->isPlayAnimationShow_) {
818             WMError res = MinimizeStructuredAppWindowsExceptSelf(node);
819             if (res != WMError::WM_OK) {
820                 WLOGFE("Minimize other structured window failed");
821                 MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
822                 return res;
823             }
824         }
825         WMError res = container->ShowStartingWindow(node);
826         if (res != WMError::WM_OK) {
827             MinimizeApp::ClearNodesWithReason(MinimizeReason::OTHER_WINDOW);
828         }
829         return res;
830     }
831     if (WindowHelper::IsAppFullOrSplitWindow(node->GetWindowType(), node->GetWindowMode())) {
832         container->NotifyDockWindowStateChanged(node, false);
833     }
834     // limit number of main window
835     uint32_t mainWindowNumber = container->GetWindowCountByType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
836     if (mainWindowNumber >= maxAppWindowNumber_ && node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
837         container->MinimizeOldestAppWindow();
838     }
839 
840     auto parentNode = GetWindowNode(parentId);
841 
842     WMError res = BindDialogToParent(node, parentNode);
843     if (res != WMError::WM_OK) {
844         return res;
845     }
846 
847     res = container->AddWindowNode(node, parentNode);
848     if (res != WMError::WM_OK) {
849         WLOGFE("failed with ret: %{public}u", static_cast<uint32_t>(res));
850         return res;
851     }
852     return PostProcessAddWindowNode(node, parentNode, container);
853 }
854 
RemoveWindowNode(uint32_t windowId,bool fromAnimation)855 WMError WindowRoot::RemoveWindowNode(uint32_t windowId, bool fromAnimation)
856 {
857     WLOGFD("begin");
858     auto node = GetWindowNode(windowId);
859     if (node == nullptr) {
860         WLOGFE("could not find window");
861         return WMError::WM_ERROR_NULLPTR;
862     }
863     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
864     if (container == nullptr) {
865         WLOGFE("failed, window container could not be found");
866         return WMError::WM_ERROR_INVALID_DISPLAY;
867     }
868     container->DropShowWhenLockedWindowIfNeeded(node);
869     UpdateFocusWindowWithWindowRemoved(node, container);
870     UpdateActiveWindowWithWindowRemoved(node, container);
871     UpdateBrightnessWithWindowRemoved(windowId, container);
872     WMError res = container->RemoveWindowNode(node, fromAnimation);
873     if (res == WMError::WM_OK) {
874         for (auto& child : node->children_) {
875             if (child == nullptr) {
876                 break;
877             }
878             HandleKeepScreenOn(child->GetWindowId(), false);
879         }
880         HandleKeepScreenOn(windowId, false);
881     }
882 
883     if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) {
884         std::vector<sptr<WindowNode>> windowNodes;
885         container->TraverseContainer(windowNodes);
886         for (auto& winNode : windowNodes) {
887             if (winNode && WindowHelper::IsMainWindow(winNode->GetWindowType()) &&
888                 winNode->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION &&
889                 winNode->GetWindowToken()) {
890                 winNode->GetWindowToken()->NotifyForegroundInteractiveStatus(true);
891             }
892         }
893     }
894 
895     return res;
896 }
897 
UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode> & node)898 void WindowRoot::UpdateDisplayOrientationWhenHideWindow(sptr<WindowNode>& node)
899 {
900     if (!FIX_ORIENTATION_ENABLE) {
901         return;
902     }
903     WLOGFD("[FixOrientation] begin");
904     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
905     if (container == nullptr) {
906         WLOGFE("[FixOrientation] failed, window container could not be found");
907         return;
908     }
909     auto nextRotatableWindow = container->GetNextRotatableWindow(node->GetWindowId());
910     if (nextRotatableWindow != nullptr) {
911         WLOGFD("[FixOrientation] next rotatable window: %{public}u", nextRotatableWindow->GetWindowId());
912         container->SetDisplayOrientationFromWindow(nextRotatableWindow, false);
913     }
914 }
915 
SetGestureNavigaionEnabled(bool enable)916 WMError WindowRoot::SetGestureNavigaionEnabled(bool enable)
917 {
918     if (lastGestureNativeEnabled_ == enable) {
919         WLOGFW("Do not set gesture navigation too much times as same value and the value is %{public}d", enable);
920         return WMError::WM_DO_NOTHING;
921     }
922     WindowManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
923     lastGestureNativeEnabled_ = enable;
924     WLOGFD("Set gesture navigation enabled succeeded and notify result of %{public}d", enable);
925     return WMError::WM_OK;
926 }
927 
UpdateWindowNode(uint32_t windowId,WindowUpdateReason reason)928 WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason)
929 {
930     auto node = GetWindowNode(windowId);
931     if (node == nullptr) {
932         WLOGFE("could not find window");
933         return WMError::WM_ERROR_NULLPTR;
934     }
935     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
936     if (container == nullptr) {
937         WLOGFE("update window failed, window container could not be found");
938         return WMError::WM_ERROR_INVALID_DISPLAY;
939     }
940 
941     auto ret = container->UpdateWindowNode(node, reason);
942     if (ret == WMError::WM_OK && reason == WindowUpdateReason::UPDATE_FLAGS) {
943         CheckAndNotifyWaterMarkChangedResult();
944     }
945     return ret;
946 }
947 
UpdateSizeChangeReason(uint32_t windowId,WindowSizeChangeReason reason)948 WMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeReason reason)
949 {
950     auto node = GetWindowNode(windowId);
951     if (node == nullptr) {
952         WLOGFE("could not find window");
953         return WMError::WM_ERROR_NULLPTR;
954     }
955     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
956     if (container == nullptr) {
957         WLOGFE("failed, window container could not be found");
958         return WMError::WM_ERROR_INVALID_DISPLAY;
959     }
960     container->UpdateSizeChangeReason(node, reason);
961     return WMError::WM_OK;
962 }
963 
SetBrightness(uint32_t windowId,float brightness)964 void WindowRoot::SetBrightness(uint32_t windowId, float brightness)
965 {
966     auto node = GetWindowNode(windowId);
967     if (node == nullptr) {
968         WLOGFE("could not find window");
969         return;
970     }
971     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
972     if (container == nullptr) {
973         WLOGFE("failed, window container could not be found");
974         return;
975     }
976     if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
977         WLOGW("Only app window support set brightness");
978         return;
979     }
980     if (windowId != container->GetActiveWindow()) {
981         WLOGE("Window is not active with windowId:%{public}d", windowId);
982         return;
983     }
984     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) <= std::numeric_limits<float>::min()) {
985         if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) {
986             WLOGFI("value: %{public}f to restore brightness", brightness);
987 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
988             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
989 #endif
990             container->SetDisplayBrightness(brightness);
991         }
992     } else {
993         if (std::fabs(container->GetDisplayBrightness() - brightness) > std::numeric_limits<float>::min()) {
994             WLOGFI("value: %{public}u", container->ToOverrideBrightness(brightness));
995 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
996             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
997                 container->ToOverrideBrightness(brightness));
998 #endif
999             container->SetDisplayBrightness(brightness);
1000         }
1001     }
1002     container->SetBrightnessWindow(windowId);
1003 }
1004 
HandleKeepScreenOn(uint32_t windowId,bool requireLock)1005 void WindowRoot::HandleKeepScreenOn(uint32_t windowId, bool requireLock)
1006 {
1007     auto node = GetWindowNode(windowId);
1008     if (node == nullptr) {
1009         WLOGFE("could not find window");
1010         return;
1011     }
1012     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1013     if (container == nullptr) {
1014         WLOGFE("failed, window container could not be found");
1015         return;
1016     }
1017     container->HandleKeepScreenOn(node, requireLock);
1018 }
1019 
UpdateFocusableProperty(uint32_t windowId)1020 void WindowRoot::UpdateFocusableProperty(uint32_t windowId)
1021 {
1022     auto node = GetWindowNode(windowId);
1023     if (node == nullptr) {
1024         WLOGFE("could not find window");
1025         return;
1026     }
1027     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1028     if (container == nullptr) {
1029         WLOGFE("failed, window container could not be found");
1030         return;
1031     }
1032 
1033     if (windowId != container->GetFocusWindow() || node->GetWindowProperty()->GetFocusable()) {
1034         return;
1035     }
1036     auto nextFocusableWindow = container->GetNextFocusableWindow(windowId);
1037     if (nextFocusableWindow != nullptr) {
1038         WLOGI("Next focus window id: %{public}u", nextFocusableWindow->GetWindowId());
1039         container->SetFocusWindow(nextFocusableWindow->GetWindowId());
1040     }
1041 }
1042 
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)1043 WMError WindowRoot::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
1044 {
1045     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1046     if (container == nullptr) {
1047         WLOGFE("failed, window container could not be found");
1048         return WMError::WM_ERROR_INVALID_DISPLAY;
1049     }
1050     WindowMode curWinMode = node->GetWindowMode();
1051     if (curWinMode == dstMode) {
1052         return WMError::WM_OK;
1053     }
1054     auto res = container->SetWindowMode(node, dstMode);
1055     auto nextRotatableWindow = container->GetNextRotatableWindow(0);
1056     if (nextRotatableWindow != nullptr) {
1057         DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(nextRotatableWindow->GetDisplayId(),
1058             nextRotatableWindow->GetRequestedOrientation());
1059     }
1060     return res;
1061 }
1062 
DestroyWindowSelf(sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container)1063 WMError WindowRoot::DestroyWindowSelf(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container)
1064 {
1065     for (auto& child : node->children_) {
1066         if (child == nullptr) {
1067             continue;
1068         }
1069         child->parent_ = nullptr;
1070         if ((child->GetWindowToken() != nullptr) && (child->abilityToken_ != node->abilityToken_) &&
1071             (child->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1072             child->GetWindowToken()->NotifyDestroy();
1073         }
1074     }
1075     std::vector<uint32_t> windowIds;
1076     WMError res = container->DestroyWindowNode(node, windowIds);
1077     if (res != WMError::WM_OK) {
1078         WLOGFE("RemoveWindowNode failed");
1079     }
1080     return DestroyWindowInner(node);
1081 }
1082 
DestroyWindowWithChild(sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container)1083 WMError WindowRoot::DestroyWindowWithChild(sptr<WindowNode>& node, const sptr<WindowNodeContainer>& container)
1084 {
1085     auto token = node->abilityToken_;
1086     std::vector<uint32_t> windowIds;
1087     WMError res = container->DestroyWindowNode(node, windowIds);
1088     for (auto id : windowIds) {
1089         node = GetWindowNode(id);
1090         if (!node) {
1091             continue;
1092         }
1093         HandleKeepScreenOn(id, false);
1094         DestroyWindowInner(node);
1095         if ((node->GetWindowToken() != nullptr) && (node->abilityToken_ != token) &&
1096             (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1097             node->GetWindowToken()->NotifyDestroy();
1098         }
1099     }
1100     return res;
1101 }
1102 
DestroyWindow(uint32_t windowId,bool onlySelf)1103 WMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf)
1104 {
1105     auto node = GetWindowNode(windowId);
1106     if (node == nullptr) {
1107         WLOGFE("failed, because window node is not exist.");
1108         return WMError::WM_ERROR_NULLPTR;
1109     }
1110     WLOGI("windowId %{public}u, onlySelf:%{public}u.", windowId, onlySelf);
1111     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1112     if (!container) {
1113         WLOGFW("failed, window container could not be found");
1114         return DestroyWindowInner(node);
1115     }
1116 
1117     UpdateFocusWindowWithWindowRemoved(node, container);
1118     UpdateActiveWindowWithWindowRemoved(node, container);
1119     UpdateBrightnessWithWindowRemoved(windowId, container);
1120     HandleKeepScreenOn(windowId, false);
1121     if (onlySelf) {
1122         return DestroyWindowSelf(node, container);
1123     } else {
1124         return DestroyWindowWithChild(node, container);
1125     }
1126 }
1127 
DestroyWindowInner(sptr<WindowNode> & node)1128 WMError WindowRoot::DestroyWindowInner(sptr<WindowNode>& node)
1129 {
1130     if (node == nullptr) {
1131         WLOGFE("window has been destroyed");
1132         return WMError::WM_ERROR_DESTROYED_OBJECT;
1133     }
1134 
1135     if (node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
1136         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
1137         node->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
1138         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
1139             node->GetCallingUid(), node->GetVisibilityState(), node->GetWindowType()));
1140         WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, visibilityState:%{public}d",
1141             node->GetWindowId(), node->GetVisibilityState());
1142         WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
1143 
1144         CheckAndNotifyWaterMarkChangedResult();
1145     }
1146 
1147     auto cmpFunc = [node](const std::map<uint64_t, sptr<WindowNode>>::value_type& pair) {
1148         if (pair.second == nullptr) {
1149             return false;
1150         }
1151         if (pair.second->GetWindowId() == node->GetWindowId()) {
1152             return true;
1153         }
1154         return false;
1155     };
1156     auto iter = std::find_if(surfaceIdWindowNodeMap_.begin(), surfaceIdWindowNodeMap_.end(), cmpFunc);
1157     if (iter != surfaceIdWindowNodeMap_.end()) {
1158         surfaceIdWindowNodeMap_.erase(iter);
1159     }
1160 
1161     sptr<IWindow> window = node->GetWindowToken();
1162     if ((window != nullptr) && (window->AsObject() != nullptr)) {
1163         if (windowIdMap_.count(window->AsObject()) == 0) {
1164             WLOGE("window remote object has been destroyed");
1165             return WMError::WM_ERROR_DESTROYED_OBJECT;
1166         }
1167 
1168         if (window->AsObject() != nullptr) {
1169             window->AsObject()->RemoveDeathRecipient(windowDeath_);
1170         }
1171         windowIdMap_.erase(window->AsObject());
1172     }
1173     windowNodeMap_.erase(node->GetWindowId());
1174     WLOGI("destroy window use_count:%{public}d", node->GetSptrRefCount());
1175     return WMError::WM_OK;
1176 }
1177 
UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container) const1178 void WindowRoot::UpdateFocusWindowWithWindowRemoved(const sptr<WindowNode>& node,
1179     const sptr<WindowNodeContainer>& container) const
1180 {
1181     if (node == nullptr || container == nullptr) {
1182         WLOGFE("window is invalid");
1183         return;
1184     }
1185     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1186         WLOGI("window is divider, do not get next focus window.");
1187         return;
1188     }
1189     uint32_t windowId = node->GetWindowId();
1190     uint32_t focusedWindowId = container->GetFocusWindow();
1191     WLOGFI("current window: %{public}u, focus window: %{public}u", windowId, focusedWindowId);
1192     container->DumpScreenWindowTree();
1193     if (windowId != focusedWindowId) {
1194         auto iter = std::find_if(node->children_.begin(), node->children_.end(),
1195             [focusedWindowId](sptr<WindowNode> node) {
1196                 return node->GetWindowId() == focusedWindowId;
1197             });
1198         if (iter == node->children_.end()) {
1199             return;
1200         }
1201     }
1202     if (!node->children_.empty()) {
1203         auto firstChild = node->children_.front();
1204         if (firstChild->priority_ < 0) {
1205             windowId = firstChild->GetWindowId();
1206         }
1207     }
1208 
1209     auto nextFocusableWindow = container->GetNextFocusableWindow(windowId);
1210     if (nextFocusableWindow != nullptr) {
1211         WLOGFI("adjust focus window, next focus window id: %{public}u", nextFocusableWindow->GetWindowId());
1212         container->SetFocusWindow(nextFocusableWindow->GetWindowId());
1213     } else {
1214         WLOGFW("next focus window is invalid");
1215         container->SetFocusWindow(INVALID_WINDOW_ID);
1216     }
1217 }
1218 
UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode> & node,const sptr<WindowNodeContainer> & container) const1219 void WindowRoot::UpdateActiveWindowWithWindowRemoved(const sptr<WindowNode>& node,
1220     const sptr<WindowNodeContainer>& container) const
1221 {
1222     if (node == nullptr || container == nullptr) {
1223         WLOGFE("window is invalid");
1224         return;
1225     }
1226     uint32_t windowId = node->GetWindowId();
1227     uint32_t activeWindowId = container->GetActiveWindow();
1228     WLOGFD("current window: %{public}u, active window: %{public}u", windowId, activeWindowId);
1229     if (windowId != activeWindowId) {
1230         auto iter = std::find_if(node->children_.begin(), node->children_.end(),
1231             [activeWindowId](sptr<WindowNode> node) {
1232                 return node->GetWindowId() == activeWindowId;
1233             });
1234         if (iter == node->children_.end()) {
1235             return;
1236         }
1237     }
1238     if (!node->children_.empty()) {
1239         auto firstChild = node->children_.front();
1240         if (firstChild->priority_ < 0) {
1241             windowId = firstChild->GetWindowId();
1242         }
1243     }
1244 
1245     auto nextActiveWindow = container->GetNextActiveWindow(windowId);
1246     if (nextActiveWindow != nullptr) {
1247         WLOGI("Next active window id: %{public}u", nextActiveWindow->GetWindowId());
1248         container->SetActiveWindow(nextActiveWindow->GetWindowId(), true);
1249     }
1250 }
1251 
UpdateBrightnessWithWindowRemoved(uint32_t windowId,const sptr<WindowNodeContainer> & container) const1252 void WindowRoot::UpdateBrightnessWithWindowRemoved(uint32_t windowId, const sptr<WindowNodeContainer>& container) const
1253 {
1254     if (container == nullptr) {
1255         WLOGFE("window container could not be found");
1256         return;
1257     }
1258     if (windowId == container->GetBrightnessWindow()) {
1259         WLOGFD("winId: %{public}u", container->GetActiveWindow());
1260         container->UpdateBrightness(container->GetActiveWindow(), true);
1261     }
1262 }
1263 
IsVerticalDisplay(sptr<WindowNode> & node) const1264 bool WindowRoot::IsVerticalDisplay(sptr<WindowNode>& node) const
1265 {
1266     auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId());
1267     if (container == nullptr) {
1268         WLOGFE("get display direction failed, window container could not be found");
1269         return false;
1270     }
1271     return container->IsVerticalDisplay(node->GetDisplayId());
1272 }
1273 
RequestFocus(uint32_t windowId)1274 WMError WindowRoot::RequestFocus(uint32_t windowId)
1275 {
1276     auto node = GetWindowNode(windowId);
1277     if (node == nullptr) {
1278         WLOGFE("could not find window");
1279         return WMError::WM_ERROR_NULLPTR;
1280     }
1281     if (!node->currentVisibility_) {
1282         WLOGFE("could not request focus before it does not be shown");
1283         return WMError::WM_ERROR_INVALID_OPERATION;
1284     }
1285     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1286     if (container == nullptr) {
1287         WLOGFE("window container could not be found");
1288         return WMError::WM_ERROR_NULLPTR;
1289     }
1290     if (node->GetWindowProperty()->GetFocusable()) {
1291         return container->SetFocusWindow(windowId);
1292     }
1293     return WMError::WM_ERROR_INVALID_OPERATION;
1294 }
1295 
RequestActiveWindow(uint32_t windowId)1296 WMError WindowRoot::RequestActiveWindow(uint32_t windowId)
1297 {
1298     auto node = GetWindowNode(windowId);
1299     if (node == nullptr) {
1300         WLOGFE("could not find window");
1301         return WMError::WM_ERROR_NULLPTR;
1302     }
1303     if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1304         WLOGFE("window could not be active window");
1305         return WMError::WM_ERROR_INVALID_TYPE;
1306     }
1307     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1308     if (container == nullptr) {
1309         WLOGFE("window container could not be found");
1310         return WMError::WM_ERROR_NULLPTR;
1311     }
1312     auto res = container->SetActiveWindow(windowId, false);
1313     WLOGFD("windowId:%{public}u, name:%{public}s, orientation:%{public}u, type:%{public}u, isMainWindow:%{public}d",
1314         windowId, node->GetWindowName().c_str(), static_cast<uint32_t>(node->GetRequestedOrientation()),
1315         node->GetWindowType(), WindowHelper::IsMainWindow(node->GetWindowType()));
1316     return res;
1317 }
1318 
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1319 void WindowRoot::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1320 {
1321     for (auto& elem : windowNodeContainerMap_) {
1322         if (elem.second == nullptr) {
1323             continue;
1324         }
1325         elem.second->ProcessWindowStateChange(state, reason);
1326     }
1327 }
1328 
NotifySystemBarTints()1329 void WindowRoot::NotifySystemBarTints()
1330 {
1331     WLOGFD("notify current system bar tints");
1332     for (auto& it : windowNodeContainerMap_) {
1333         if (it.second != nullptr) {
1334             it.second->NotifySystemBarTints(displayIdMap_[it.first]);
1335         }
1336     }
1337 }
1338 
NotifyDesktopUnfrozen()1339 WMError WindowRoot::NotifyDesktopUnfrozen()
1340 {
1341     WLOGFD("notify desktop unfrozen");
1342     for (const auto& it : windowNodeMap_) {
1343         auto& node = it.second;
1344         // just need notify desktop unfrozen when desktop shown
1345         // since unfrozen will change window state to shown
1346         if (node && (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP)
1347             && (node->GetWindowToken()) && node->currentVisibility_) {
1348             node->GetWindowToken()->UpdateWindowState(WindowState::STATE_UNFROZEN);
1349             return WMError::WM_OK;
1350         }
1351     }
1352     WLOGFD("notify desktop unfrozen failed, maybe no window node or windowToken!");
1353     return WMError::WM_ERROR_INVALID_OPERATION;
1354 }
1355 
FindWallpaperWindow()1356 sptr<WindowNode> WindowRoot::FindWallpaperWindow()
1357 {
1358     auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(),
1359         [](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) {
1360             return pair.second->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER;
1361         });
1362     if (iter == windowNodeMap_.end()) {
1363         WLOGI("cannot find windowNode");
1364         return nullptr;
1365     }
1366     return iter->second;
1367 }
1368 
RaiseZOrderForAppWindow(sptr<WindowNode> & node)1369 WMError WindowRoot::RaiseZOrderForAppWindow(sptr<WindowNode>& node)
1370 {
1371     if (node == nullptr) {
1372         WLOGFW("add window failed, node is nullptr");
1373         return WMError::WM_ERROR_NULLPTR;
1374     }
1375     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1376         auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1377         if (container == nullptr) {
1378             WLOGFW("window container could not be found");
1379             return WMError::WM_ERROR_NULLPTR;
1380         }
1381         container->RaiseSplitRelatedWindowToTop(node);
1382         return WMError::WM_OK;
1383     }
1384     if (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1385         auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1386         if (container == nullptr) {
1387             WLOGFW("window container could not be found");
1388             return WMError::WM_ERROR_NULLPTR;
1389         }
1390         sptr<WindowNode> parentNode = FindMainWindowWithToken(node->dialogTargetToken_);
1391         if (parentNode != nullptr) {
1392             container->RaiseZOrderForAppWindow(node, parentNode);
1393         }
1394         return WMError::WM_OK;
1395     }
1396 
1397     if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
1398         WLOGFW("window is not app window");
1399         return WMError::WM_ERROR_INVALID_TYPE;
1400     }
1401     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1402     if (container == nullptr) {
1403         WLOGFW("add window failed, window container could not be found");
1404         return WMError::WM_ERROR_NULLPTR;
1405     }
1406 
1407     auto parentNode = GetWindowNode(node->GetParentId());
1408     return container->RaiseZOrderForAppWindow(node, parentNode);
1409 }
1410 
DispatchKeyEvent(sptr<WindowNode> node,std::shared_ptr<MMI::KeyEvent> event)1411 void WindowRoot::DispatchKeyEvent(sptr<WindowNode> node, std::shared_ptr<MMI::KeyEvent> event)
1412 {
1413     sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1414     if (container == nullptr) {
1415         WLOGFW("window container could not be found");
1416         return;
1417     }
1418     std::vector<sptr<WindowNode>> windowNodes;
1419     container->TraverseContainer(windowNodes);
1420     auto iter = std::find(windowNodes.begin(), windowNodes.end(), node);
1421     if (iter == windowNodes.end()) {
1422         WLOGFE("Cannot find node");
1423         return;
1424     }
1425     for (++iter; iter != windowNodes.end(); ++iter) {
1426         if (*iter == nullptr) {
1427             WLOGFE("Node is null");
1428             continue;
1429         }
1430         if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
1431             WLOGFI("Skip component window: %{public}u", (*iter)->GetWindowId());
1432             continue;
1433         }
1434         if (WindowHelper::IsAppWindow((*iter)->GetWindowType())) {
1435             WLOGFI("App window: %{public}u", (*iter)->GetWindowId());
1436             if ((*iter)->GetWindowToken()) {
1437                 (*iter)->GetWindowToken()->ConsumeKeyEvent(event);
1438             }
1439             break;
1440         }
1441         WLOGFI("Unexpected window: %{public}u", (*iter)->GetWindowId());
1442         break;
1443     }
1444 }
1445 
GetWindowIdByObject(const sptr<IRemoteObject> & remoteObject)1446 uint32_t WindowRoot::GetWindowIdByObject(const sptr<IRemoteObject>& remoteObject)
1447 {
1448     auto iter = windowIdMap_.find(remoteObject);
1449     return iter == std::end(windowIdMap_) ? INVALID_WINDOW_ID : iter->second;
1450 }
1451 
OnRemoteDied(const sptr<IRemoteObject> & remoteObject)1452 void WindowRoot::OnRemoteDied(const sptr<IRemoteObject>& remoteObject)
1453 {
1454     callback_(Event::REMOTE_DIED, remoteObject);
1455 }
1456 
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)1457 WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
1458 {
1459     if (windowNodeMap_.find(mainWinId) == windowNodeMap_.end()) {
1460         return WMError::WM_ERROR_INVALID_WINDOW;
1461     }
1462     auto node = windowNodeMap_[mainWinId];
1463     if (!node->currentVisibility_) {
1464         return WMError::WM_ERROR_INVALID_WINDOW;
1465     }
1466     if (!node->children_.empty()) {
1467         auto iter = node->children_.rbegin();
1468         if (WindowHelper::IsSubWindow((*iter)->GetWindowType()) ||
1469             WindowHelper::IsSystemSubWindow((*iter)->GetWindowType())) {
1470             topWinId = (*iter)->GetWindowId();
1471             return WMError::WM_OK;
1472         }
1473     }
1474     topWinId = mainWinId;
1475     return WMError::WM_OK;
1476 }
1477 
SetWindowLayoutMode(DisplayId displayId,WindowLayoutMode mode)1478 WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode)
1479 {
1480     auto container = GetOrCreateWindowNodeContainer(displayId);
1481     if (container == nullptr) {
1482         WLOGFE("window container could not be found");
1483         return WMError::WM_ERROR_NULLPTR;
1484     }
1485     WMError ret = container->SwitchLayoutPolicy(mode, displayId, true);
1486     if (ret != WMError::WM_OK) {
1487         WLOGFW("set window layout mode failed displayId: %{public}" PRIu64 ", ret: %{public}d", displayId, ret);
1488     }
1489     return ret;
1490 }
1491 
GetAllDisplayIds() const1492 std::vector<DisplayId> WindowRoot::GetAllDisplayIds() const
1493 {
1494     std::vector<DisplayId> displayIds;
1495     for (auto& it : windowNodeContainerMap_) {
1496         if (!it.second) {
1497             return {};
1498         }
1499         std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[it.first];
1500         for (auto displayId : displayIdVec) {
1501             displayIds.push_back(displayId);
1502         }
1503     }
1504     return displayIds;
1505 }
1506 
GenAllWindowsLogInfo() const1507 std::string WindowRoot::GenAllWindowsLogInfo() const
1508 {
1509     std::ostringstream os;
1510     WindowNodeOperationFunc func = [&os](sptr<WindowNode> node) {
1511         if (node == nullptr) {
1512             WLOGE("WindowNode is nullptr");
1513             return false;
1514         }
1515         os<<"window_name:"<<node->GetWindowName()<<",id:"<<node->GetWindowId()<<
1516            ",focusable:"<<node->GetWindowProperty()->GetFocusable()<<";";
1517         return false;
1518     };
1519 
1520     for (auto& elem : windowNodeContainerMap_) {
1521         if (elem.second == nullptr) {
1522             continue;
1523         }
1524         std::vector<DisplayId>& displayIdVec = const_cast<WindowRoot*>(this)->displayIdMap_[elem.first];
1525         for (const auto& displayId : displayIdVec) {
1526             os << "Display " << displayId << ":";
1527         }
1528         elem.second->TraverseWindowTree(func, true);
1529     }
1530     return os.str();
1531 }
1532 
FocusFaultDetection() const1533 void WindowRoot::FocusFaultDetection() const
1534 {
1535     if (!needCheckFocusWindow) {
1536         return;
1537     }
1538     bool needReport = true;
1539     uint32_t focusWinId = INVALID_WINDOW_ID;
1540     for (auto& elem : windowNodeContainerMap_) {
1541         if (elem.second == nullptr) {
1542             continue;
1543         }
1544         focusWinId = elem.second->GetFocusWindow();
1545         if (focusWinId != INVALID_WINDOW_ID) {
1546             needReport = false;
1547             sptr<WindowNode> windowNode = GetWindowNode(focusWinId);
1548             if (windowNode == nullptr || !windowNode->currentVisibility_) {
1549                 needReport = true;
1550                 WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId);
1551                 break;
1552             }
1553         }
1554     }
1555     if (needReport) {
1556         std::string windowLog(GenAllWindowsLogInfo());
1557         WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str());
1558         int32_t ret = HiSysEventWrite(
1559             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1560             "NO_FOCUS_WINDOW",
1561             OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1562             "PID", getpid(),
1563             "UID", getuid(),
1564             "PACKAGE_NAME", "foundation",
1565             "PROCESS_NAME", "foundation",
1566             "MSG", windowLog);
1567         if (ret != 0) {
1568             WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
1569         }
1570     }
1571 }
1572 
ProcessExpandDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,std::map<DisplayId,Rect> & displayRectMap)1573 void WindowRoot::ProcessExpandDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1574     std::map<DisplayId, Rect>& displayRectMap)
1575 {
1576     if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) {
1577         WLOGFE("get display failed or get invalid display info");
1578         return;
1579     }
1580     DisplayGroupInfo::GetInstance().SetDefaultDisplayId(defaultDisplayId);
1581     DisplayId displayId = displayInfo->GetDisplayId();
1582     ScreenId displayGroupId = displayInfo->GetScreenGroupId();
1583     auto container = windowNodeContainerMap_[displayGroupId];
1584     if (container == nullptr) {
1585         WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1586         return;
1587     }
1588 
1589     container->GetDisplayGroupController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap);
1590     container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_);
1591     WLOGI("Container exist, add new display, displayId: %{public}" PRIu64"", displayId);
1592 }
1593 
GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo)1594 std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDMS(sptr<DisplayInfo> displayInfo)
1595 {
1596     std::map<DisplayId, Rect> displayRectMap;
1597 
1598     if (displayInfo == nullptr) {
1599         return displayRectMap;
1600     }
1601 
1602     for (auto& displayId : displayIdMap_[displayInfo->GetScreenGroupId()]) {
1603         auto info = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId);
1604         Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() };
1605         displayRectMap.insert(std::make_pair(displayId, displayRect));
1606 
1607         WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]",
1608             displayId, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_);
1609     }
1610     return displayRectMap;
1611 }
1612 
GetAllDisplayRectsByDisplayInfo(const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1613 std::map<DisplayId, Rect> WindowRoot::GetAllDisplayRectsByDisplayInfo(
1614     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1615 {
1616     std::map<DisplayId, Rect> displayRectMap;
1617 
1618     for (const auto& iter : displayInfoMap) {
1619         auto id = iter.first;
1620         auto info = iter.second;
1621         Rect displayRect = { info->GetOffsetX(), info->GetOffsetY(), info->GetWidth(), info->GetHeight() };
1622         displayRectMap.insert(std::make_pair(id, displayRect));
1623 
1624         WLOGI("displayId: %{public}" PRIu64", displayRect: [ %{public}d, %{public}d, %{public}d, %{public}d]",
1625             id, displayRect.posX_, displayRect.posY_, displayRect.width_, displayRect.height_);
1626     }
1627     return displayRectMap;
1628 }
1629 
ProcessDisplayCreate(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1630 void WindowRoot::ProcessDisplayCreate(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1631     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1632 {
1633     DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId();
1634     ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId();
1635     auto iter = windowNodeContainerMap_.find(displayGroupId);
1636     if (iter == windowNodeContainerMap_.end()) {
1637         CreateWindowNodeContainer(defaultDisplayId, displayInfo);
1638         WLOGI("Create new container for display, displayId: %{public}" PRIu64"", displayId);
1639     } else {
1640         auto& displayIdVec = displayIdMap_[displayGroupId];
1641         if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) {
1642             WLOGI("Current display is already exist, displayId: %{public}" PRIu64"", displayId);
1643             return;
1644         }
1645         // add displayId in displayId vector
1646         displayIdMap_[displayGroupId].push_back(displayId);
1647         auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1648         ProcessExpandDisplayCreate(defaultDisplayId, displayInfo, displayRectMap);
1649     }
1650 }
1651 
MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId,DisplayId displayId)1652 void WindowRoot::MoveNotShowingWindowToDefaultDisplay(DisplayId defaultDisplayId, DisplayId displayId)
1653 {
1654     for (auto& elem : windowNodeMap_) {
1655         auto& windowNode = elem.second;
1656         if (windowNode->GetDisplayId() == displayId && !windowNode->currentVisibility_) {
1657             std::vector<DisplayId> newShowingDisplays = { defaultDisplayId };
1658             windowNode->SetShowingDisplays(newShowingDisplays);
1659             windowNode->isShowingOnMultiDisplays_ = false;
1660             if (windowNode->GetWindowToken()) {
1661                 windowNode->GetWindowToken()->UpdateDisplayId(windowNode->GetDisplayId(), defaultDisplayId);
1662             }
1663             windowNode->SetDisplayId(defaultDisplayId);
1664         }
1665     }
1666 }
1667 
ProcessDisplayDestroy(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap)1668 void WindowRoot::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1669     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap)
1670 {
1671     DisplayId displayId = (displayInfo == nullptr) ? DISPLAY_ID_INVALID : displayInfo->GetDisplayId();
1672     ScreenId displayGroupId = (displayInfo == nullptr) ? SCREEN_ID_INVALID : displayInfo->GetScreenGroupId();
1673     auto& displayIdVec = displayIdMap_[displayGroupId];
1674 
1675     auto iter = windowNodeContainerMap_.find(displayGroupId);
1676     if (iter == windowNodeContainerMap_.end() ||
1677         std::find(displayIdVec.begin(), displayIdVec.end(), displayId) == displayIdVec.end() ||
1678         displayInfoMap.find(displayId) == displayInfoMap.end()) {
1679         WLOGFE("could not find display, destroy failed, displayId: %{public}" PRIu64"", displayId);
1680         return;
1681     }
1682 
1683     // erase displayId in displayIdMap
1684     auto displayIter = std::remove(displayIdVec.begin(), displayIdVec.end(), displayId);
1685     displayIdVec.erase(displayIter, displayIdVec.end());
1686 
1687     // container process display destroy
1688     auto container = iter->second;
1689     if (container == nullptr) {
1690         WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1691         return;
1692     }
1693     WLOGI("displayId: %{public}" PRIu64"", displayId);
1694 
1695     std::vector<uint32_t> needDestroyWindows;
1696     auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1697     // erase displayId in displayRectMap
1698     auto displayRectIter = displayRectMap.find(displayId);
1699     if (displayRectIter == displayRectMap.end()) {
1700         return;
1701     }
1702     displayRectMap.erase(displayRectIter);
1703     container->GetDisplayGroupController()->ProcessDisplayDestroy(
1704         defaultDisplayId, displayInfo, displayRectMap, needDestroyWindows);
1705     for (auto id : needDestroyWindows) {
1706         auto node = GetWindowNode(id);
1707         if (node != nullptr) {
1708             DestroyWindowInner(node);
1709         }
1710     }
1711     // move window which is not showing on destroyed display to default display
1712     MoveNotShowingWindowToDefaultDisplay(defaultDisplayId, displayId);
1713     WLOGI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId);
1714 }
1715 
ProcessDisplayChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)1716 void WindowRoot::ProcessDisplayChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
1717     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
1718 {
1719     if (displayInfo == nullptr) {
1720         WLOGFE("get display failed");
1721         return;
1722     }
1723     DisplayId displayId = displayInfo->GetDisplayId();
1724     ScreenId displayGroupId = displayInfo->GetScreenGroupId();
1725     auto& displayIdVec = displayIdMap_[displayGroupId];
1726     auto iter = windowNodeContainerMap_.find(displayGroupId);
1727     if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(),
1728         displayIdVec.end(), displayId) == displayIdVec.end()) {
1729         WLOGFE("[Display Change] could not find display, change failed, displayId: %{public}" PRIu64"", displayId);
1730         return;
1731     }
1732     // container process display change
1733     auto container = iter->second;
1734     if (container == nullptr) {
1735         WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId);
1736         return;
1737     }
1738 
1739     auto displayRectMap = GetAllDisplayRectsByDisplayInfo(displayInfoMap);
1740     container->GetDisplayGroupController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type);
1741 }
1742 
GetDisplayGroupRect(DisplayId displayId) const1743 Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const
1744 {
1745     Rect fullDisplayRect;
1746     auto container = const_cast<WindowRoot*>(this)->GetOrCreateWindowNodeContainer(displayId);
1747     if (container == nullptr) {
1748         WLOGFE("window container could not be found");
1749         return fullDisplayRect;
1750     }
1751     return container->GetDisplayGroupRect();
1752 }
1753 
HasPrivateWindow(DisplayId displayId)1754 bool WindowRoot::HasPrivateWindow(DisplayId displayId)
1755 {
1756     auto container = GetWindowNodeContainer(displayId);
1757     return container != nullptr ? container->HasPrivateWindow() : false;
1758 }
1759 
HasMainFullScreenWindowShown(DisplayId displayId)1760 bool WindowRoot::HasMainFullScreenWindowShown(DisplayId displayId)
1761 {
1762     auto container = GetWindowNodeContainer(displayId);
1763     return container != nullptr ? container->HasMainFullScreenWindowShown() : false;
1764 }
1765 
SetMaxAppWindowNumber(uint32_t windowNum)1766 void WindowRoot::SetMaxAppWindowNumber(uint32_t windowNum)
1767 {
1768     maxAppWindowNumber_ = windowNum;
1769 }
1770 
SetSplitRatios(const std::vector<float> & splitRatioNumbers)1771 void WindowRoot::SetSplitRatios(const std::vector<float>& splitRatioNumbers)
1772 {
1773     auto& splitRatios = splitRatioConfig_.splitRatios;
1774     splitRatios.clear();
1775     splitRatios = splitRatioNumbers;
1776     for (auto iter = splitRatios.begin(); iter != splitRatios.end();) {
1777         if (*iter > 0 && *iter < 1) { // valid ratio range (0, 1)
1778             iter++;
1779         } else {
1780             iter = splitRatios.erase(iter);
1781         }
1782     }
1783     std::sort(splitRatios.begin(), splitRatios.end());
1784     auto iter = std::unique(splitRatios.begin(), splitRatios.end());
1785     splitRatios.erase(iter, splitRatios.end()); // remove duplicate ratios
1786 }
1787 
SetExitSplitRatios(const std::vector<float> & exitSplitRatios)1788 void WindowRoot::SetExitSplitRatios(const std::vector<float>& exitSplitRatios)
1789 {
1790     if (exitSplitRatios.size() != 2) { // 2 is size of vector.
1791         return;
1792     }
1793     if (exitSplitRatios[0] > 0 && exitSplitRatios[0] < DEFAULT_SPLIT_RATIO) {
1794         splitRatioConfig_.exitSplitStartRatio = exitSplitRatios[0];
1795     }
1796     if (exitSplitRatios[1] > DEFAULT_SPLIT_RATIO && exitSplitRatios[1] < 1) {
1797         splitRatioConfig_.exitSplitEndRatio = exitSplitRatios[1];
1798     }
1799 }
1800 
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)1801 WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId,
1802     ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config)
1803 {
1804     auto container = GetOrCreateWindowNodeContainer(displayId);
1805     if (container == nullptr) {
1806         WLOGFE("GetModeChangeHotZones failed, window container could not be found");
1807         return WMError::WM_ERROR_NULLPTR;
1808     }
1809     container->GetModeChangeHotZones(displayId, hotZones, config);
1810     return WMError::WM_OK;
1811 }
1812 
RemoveSingleUserWindowNodes(int accountId)1813 void WindowRoot::RemoveSingleUserWindowNodes(int accountId)
1814 {
1815     std::vector<DisplayId> displayIds = GetAllDisplayIds();
1816     for (auto id : displayIds) {
1817         sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(id);
1818         if (container == nullptr) {
1819             WLOGW("get container failed %{public}" PRIu64"", id);
1820             continue;
1821         }
1822         container->RemoveSingleUserWindowNodes(accountId);
1823     }
1824 }
1825 
UpdateRsTree(uint32_t windowId,bool isAdd)1826 WMError WindowRoot::UpdateRsTree(uint32_t windowId, bool isAdd)
1827 {
1828     sptr<WindowNode> node = GetWindowNode(windowId);
1829     if (node == nullptr) {
1830         WLOGFE("could not find window");
1831         return WMError::WM_ERROR_NULLPTR;
1832     }
1833     auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
1834     if (container == nullptr) {
1835         WLOGFE("window container could not be found");
1836         return WMError::WM_ERROR_NULLPTR;
1837     }
1838     for (auto& displayId : node->GetShowingDisplays()) {
1839         if (isAdd) {
1840             container->AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
1841         } else {
1842             container->RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
1843         }
1844     }
1845     RSTransaction::FlushImplicitTransaction();
1846     return WMError::WM_OK;
1847 }
1848 
FindMainWindowWithToken(sptr<IRemoteObject> token)1849 sptr<WindowNode> WindowRoot::FindMainWindowWithToken(sptr<IRemoteObject> token)
1850 {
1851     auto iter = std::find_if(windowNodeMap_.begin(), windowNodeMap_.end(),
1852         [token](const std::map<uint32_t, sptr<WindowNode>>::value_type& pair) {
1853             if (WindowHelper::IsMainWindow(pair.second->GetWindowType())) {
1854                 return pair.second->abilityToken_ == token;
1855             }
1856             return false;
1857         });
1858     if (iter == windowNodeMap_.end()) {
1859         WLOGI("cannot find windowNode");
1860         return nullptr;
1861     }
1862     return iter->second;
1863 }
1864 
CheckMultiDialogWindows(WindowType type,sptr<IRemoteObject> token)1865 bool WindowRoot::CheckMultiDialogWindows(WindowType type, sptr<IRemoteObject> token)
1866 {
1867     if (type != WindowType::WINDOW_TYPE_DIALOG) {
1868         return false;
1869     }
1870 
1871     sptr<WindowNode> newCaller, oriCaller;
1872 
1873     newCaller = FindMainWindowWithToken(token);
1874     if (newCaller == nullptr) {
1875         return false;
1876     }
1877 
1878     for (auto& iter : windowNodeMap_) {
1879         if (iter.second->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1880             oriCaller = FindMainWindowWithToken(iter.second->dialogTargetToken_);
1881             if (oriCaller == newCaller) {
1882                 return true;
1883             }
1884         }
1885     }
1886 
1887     return false;
1888 }
1889 
GetWindowNodeByAbilityToken(const sptr<IRemoteObject> & abilityToken)1890 sptr<WindowNode> WindowRoot::GetWindowNodeByAbilityToken(const sptr<IRemoteObject>& abilityToken)
1891 {
1892     for (const auto& iter : windowNodeMap_) {
1893         if (iter.second != nullptr && iter.second->abilityToken_ == abilityToken) {
1894             return iter.second;
1895         }
1896     }
1897     WLOGFE("could not find required abilityToken!");
1898     return nullptr;
1899 }
1900 
TakeWindowPairSnapshot(DisplayId displayId)1901 bool WindowRoot::TakeWindowPairSnapshot(DisplayId displayId)
1902 {
1903     auto container = GetWindowNodeContainer(displayId);
1904     return container == nullptr ? false : container->TakeWindowPairSnapshot(displayId);
1905 }
1906 
ClearWindowPairSnapshot(DisplayId displayId)1907 void WindowRoot::ClearWindowPairSnapshot(DisplayId displayId)
1908 {
1909     auto container = GetWindowNodeContainer(displayId);
1910     if (container == nullptr) {
1911         WLOGFE("clear window pair snapshot failed, because container in null");
1912         return;
1913     }
1914     return container->ClearWindowPairSnapshot(displayId);
1915 }
1916 
CheckAndNotifyWaterMarkChangedResult()1917 void WindowRoot::CheckAndNotifyWaterMarkChangedResult()
1918 {
1919     auto searchWaterMarkWindow = [](wptr<WindowNode> node) {
1920         return (node != nullptr && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION &&
1921                 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)));
1922     };
1923     bool currentWaterMarkState = false;
1924     for (auto& containerPair : windowNodeContainerMap_) {
1925         auto container = containerPair.second;
1926         if (container == nullptr) {
1927             continue;
1928         }
1929         std::vector<sptr<WindowNode>> allWindowNode;
1930         container->TraverseContainer(allWindowNode);
1931         auto itor = std::find_if(allWindowNode.begin(), allWindowNode.end(), searchWaterMarkWindow);
1932         if (itor != allWindowNode.end()) {
1933             currentWaterMarkState = true;
1934             break;
1935         }
1936     }
1937     if (lastWaterMarkShowStates_ != currentWaterMarkState) {
1938         WLOGFD("WaterMarkWindows has been changed. lastWaterMarkState : %{public}d, newState:%{public}d",
1939             lastWaterMarkShowStates_, currentWaterMarkState);
1940         WindowManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(currentWaterMarkState);
1941         lastWaterMarkShowStates_ = currentWaterMarkState;
1942     }
1943 }
1944 } // namespace Rosen
1945 } // namespace OHOS
1946