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