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