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