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