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