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