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