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