1 /*
2 * Copyright (c) 2021 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_node_container.h"
17
18 #include <ability_manager_client.h>
19 #include <algorithm>
20 #include <cinttypes>
21 #include <ctime>
22 #include <display_power_mgr_client.h>
23 #include <power_mgr_client.h>
24
25 #include "common_event_manager.h"
26 #include "display_manager_service_inner.h"
27 #include "dm_common.h"
28 #include "window_helper.h"
29 #include "window_inner_manager.h"
30 #include "window_layout_policy_cascade.h"
31 #include "window_layout_policy_tile.h"
32 #include "window_manager_agent_controller.h"
33 #include "window_manager_hilog.h"
34 #include "wm_common.h"
35 #include "wm_common_inner.h"
36 #include "wm_trace.h"
37
38 namespace OHOS {
39 namespace Rosen {
40 namespace {
41 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowNodeContainer"};
42 constexpr int WINDOW_NAME_MAX_LENGTH = 10;
43 const std::string SPLIT_SCREEN_EVENT_NAME = "common.event.SPLIT_SCREEN";
44 const char DISABLE_WINDOW_ANIMATION_PATH[] = "/etc/disable_window_animation";
45 constexpr uint32_t MAX_BRIGHTNESS = 255;
46 }
47
WindowNodeContainer(DisplayId displayId,uint32_t width,uint32_t height)48 WindowNodeContainer::WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height) : displayId_(displayId)
49 {
50 displayRect_ = {
51 .posX_ = 0,
52 .posY_ = 0,
53 .width_ = width,
54 .height_ = height
55 };
56 layoutPolicys_[WindowLayoutMode::CASCADE] =
57 new WindowLayoutPolicyCascade(displayRect_, displayId_,
58 belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_);
59 layoutPolicys_[WindowLayoutMode::TILE] =
60 new WindowLayoutPolicyTile(displayRect_, displayId_,
61 belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_);
62 layoutPolicy_ = layoutPolicys_[WindowLayoutMode::CASCADE];
63 layoutPolicy_->Launch();
64 UpdateAvoidAreaFunc func = std::bind(&WindowNodeContainer::OnAvoidAreaChange, this, std::placeholders::_1);
65 avoidController_ = new AvoidAreaController(displayId, func);
66 }
67
~WindowNodeContainer()68 WindowNodeContainer::~WindowNodeContainer()
69 {
70 Destroy();
71 }
72
UpdateDisplayRect(uint32_t width,uint32_t height)73 void WindowNodeContainer::UpdateDisplayRect(uint32_t width, uint32_t height)
74 {
75 WLOGFI("update display rect, w/h=%{public}u/%{public}u", width, height);
76 displayRect_ = {
77 .posX_ = 0,
78 .posY_ = 0,
79 .width_ = width,
80 .height_ = height
81 };
82 layoutPolicy_->LayoutWindowTree();
83 }
84
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)85 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
86 {
87 std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
88 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
89 return MinimizeAppNodeExceptOptions(false, exceptionalIds, exceptionalModes);
90 }
91
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)92 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
93 {
94 if (!node->surfaceNode_) {
95 WLOGFE("surface node is nullptr!");
96 return WMError::WM_ERROR_NULLPTR;
97 }
98 sptr<WindowNode> root = FindRoot(node->GetWindowType());
99 if (root == nullptr) {
100 WLOGFE("root window node is nullptr!");
101 return WMError::WM_ERROR_NULLPTR;
102 }
103 node->requestedVisibility_ = true;
104 if (parentNode != nullptr) { // subwindow
105 if (parentNode->parent_ != root &&
106 !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
107 (parentNode->parent_ == aboveAppWindowNode_))) {
108 WLOGFE("window type and parent window not match or try to add subwindow to subwindow, which is forbidden");
109 return WMError::WM_ERROR_INVALID_PARAM;
110 }
111 node->currentVisibility_ = parentNode->currentVisibility_;
112 } else { // mainwindow
113 parentNode = root;
114 node->currentVisibility_ = true;
115 for (auto& child : node->children_) {
116 child->currentVisibility_ = child->requestedVisibility_;
117 }
118 if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
119 sysBarNodeMap_[node->GetWindowType()] = node;
120 }
121 }
122 node->parent_ = parentNode;
123
124 if (node->IsSplitMode()) {
125 WMError ret = EnterSplitWindowMode(node);
126 if (ret != WMError::WM_OK) {
127 WLOGFE("Add split window failed!");
128 return ret;
129 }
130 }
131 UpdateWindowTree(node);
132 if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
133 RaiseSplitRelatedWindowToTop(node);
134 }
135 UpdateRSTree(node, true);
136 AssignZOrder();
137 layoutPolicy_->AddWindowNode(node);
138 if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
139 avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_ADD);
140 NotifyIfSystemBarRegionChanged();
141 } else {
142 NotifyIfSystemBarTintChanged();
143 }
144 std::vector<sptr<WindowVisibilityInfo>> infos;
145 UpdateWindowVisibilityInfos(infos);
146 DumpScreenWindowTree();
147 NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
148 WLOGFI("AddWindowNode windowId: %{public}d end", node->GetWindowId());
149 return WMError::WM_OK;
150 }
151
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)152 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
153 {
154 if (!node->surfaceNode_) {
155 WLOGFE("surface node is nullptr!");
156 return WMError::WM_ERROR_NULLPTR;
157 }
158 if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
159 SwitchLayoutPolicy(WindowLayoutMode::CASCADE);
160 }
161 layoutPolicy_->UpdateWindowNode(node);
162 if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
163 avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_UPDATE);
164 NotifyIfSystemBarRegionChanged();
165 } else {
166 NotifyIfSystemBarTintChanged();
167 }
168 DumpScreenWindowTree();
169 WLOGFI("UpdateWindowNode windowId: %{public}d end", node->GetWindowId());
170 return WMError::WM_OK;
171 }
172
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)173 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
174 {
175 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
176 for (auto& childNode : appWindowNode_->children_) {
177 if (childNode->IsSplitMode()) {
178 childNode->GetWindowToken()->UpdateWindowRect(childNode->GetLayoutRect(), reason);
179 childNode->ResetWindowSizeChangeReason();
180 WLOGFI("Notify split window that the drag action is start or end, windowId: %{public}d, "
181 "reason: %{public}d", childNode->GetWindowId(), reason);
182 }
183 }
184 } else {
185 node->GetWindowToken()->UpdateWindowRect(node->GetLayoutRect(), reason);
186 node->ResetWindowSizeChangeReason();
187 WLOGFI("Notify window that the drag action is start or end, widnowId: %{public}d "
188 "reason: %{public}d", node->GetWindowId(), reason);
189 }
190 }
191
UpdateWindowTree(sptr<WindowNode> & node)192 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
193 {
194 WM_FUNCTION_TRACE();
195 node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
196 RaiseInputMethodWindowPriorityIfNeeded(node);
197 RaiseShowWhenLockedWindowIfNeeded(node);
198 auto parentNode = node->parent_;
199 auto position = parentNode->children_.end();
200 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
201 if ((*iter)->priority_ > node->priority_) {
202 position = iter;
203 break;
204 }
205 }
206 parentNode->children_.insert(position, node);
207 }
208
UpdateRSTree(sptr<WindowNode> & node,bool isAdd)209 bool WindowNodeContainer::UpdateRSTree(sptr<WindowNode>& node, bool isAdd)
210 {
211 WM_FUNCTION_TRACE();
212 static const bool IsWindowAnimationEnabled = ReadIsWindowAnimationEnabledProperty();
213
214 auto updateRSTreeFunc = [&]() {
215 auto& dms = DisplayManagerServiceInner::GetInstance();
216 if (isAdd) {
217 dms.UpdateRSTree(displayId_, node->surfaceNode_, true);
218 for (auto& child : node->children_) {
219 if (child->currentVisibility_) {
220 dms.UpdateRSTree(displayId_, child->surfaceNode_, true);
221 }
222 }
223 } else {
224 dms.UpdateRSTree(displayId_, node->surfaceNode_, false);
225 for (auto& child : node->children_) {
226 dms.UpdateRSTree(displayId_, child->surfaceNode_, false);
227 }
228 }
229 };
230
231 if (IsWindowAnimationEnabled) {
232 // default transition duration: 350ms
233 static const RSAnimationTimingProtocol timingProtocol(350);
234 // default transition curve: EASE OUT
235 static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT;
236
237 // add or remove window with transition animation
238 RSNode::Animate(timingProtocol, curve, updateRSTreeFunc);
239 } else {
240 // add or remove window without animation
241 updateRSTreeFunc();
242 }
243
244 return true;
245 }
246
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)247 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
248 {
249 WMError ret = RemoveWindowNode(node);
250 if (ret != WMError::WM_OK) {
251 WLOGFE("RemoveWindowNode failed");
252 return ret;
253 }
254 node->surfaceNode_ = nullptr;
255 windowIds.push_back(node->GetWindowId());
256
257 for (auto& child : node->children_) { // destroy sub window if exists
258 windowIds.push_back(child->GetWindowId());
259 child->parent_ = nullptr;
260 if (child->surfaceNode_ != nullptr) {
261 WLOGFI("child surfaceNode set nullptr");
262 child->surfaceNode_ = nullptr;
263 }
264 }
265 node->children_.clear();
266 return WMError::WM_OK;
267 }
268
RemoveWindowNode(sptr<WindowNode> & node)269 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node)
270 {
271 if (node == nullptr) {
272 WLOGFE("window node or surface node is nullptr, invalid");
273 return WMError::WM_ERROR_DESTROYED_OBJECT;
274 }
275 if (node->parent_ == nullptr) {
276 WLOGFW("can't find parent of this node");
277 } else {
278 // remove this node from parent
279 auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
280 if (iter != node->parent_->children_.end()) {
281 node->parent_->children_.erase(iter);
282 } else {
283 WLOGFE("can't find this node in parent");
284 }
285 node->parent_ = nullptr;
286 }
287 node->requestedVisibility_ = false;
288 node->currentVisibility_ = false;
289 node->hasDecorated_ = node->isDefultLayoutRect_ ? true : false;
290 node->isCovered_ = true;
291 std::vector<sptr<WindowVisibilityInfo>> infos = {new WindowVisibilityInfo(node->GetWindowId(),
292 node->GetCallingPid(), node->GetCallingUid(), false)};
293 for (auto& child : node->children_) {
294 if (child->currentVisibility_) {
295 child->currentVisibility_ = false;
296 child->isCovered_ = true;
297 infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(),
298 child->GetCallingUid(), false));
299 }
300 }
301
302 if (node->IsSplitMode()) {
303 WMError ret = ExitSplitWindowMode(node);
304 if (ret != WMError::WM_OK) {
305 WLOGFE("Remove split window failed!");
306 return ret;
307 }
308 }
309
310 UpdateRSTree(node, false);
311 layoutPolicy_->RemoveWindowNode(node);
312 if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
313 avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE);
314 NotifyIfSystemBarRegionChanged();
315 } else {
316 NotifyIfSystemBarTintChanged();
317 }
318 UpdateWindowVisibilityInfos(infos);
319 DumpScreenWindowTree();
320 NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED);
321 RcoveryScreenDefaultOrientationIfNeed();
322 WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId());
323 return WMError::WM_OK;
324 }
325
RcoveryScreenDefaultOrientationIfNeed()326 void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed()
327 {
328 if (appWindowNode_->children_.empty()) {
329 WLOGFI("appWindowNode_ child is empty in display %{public}" PRIu64"", displayId_);
330 DisplayManagerServiceInner::GetInstance().
331 SetOrientationFromWindow(displayId_, Orientation::UNSPECIFIED);
332 }
333 }
334
Destroy()335 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
336 {
337 removedIds_.clear();
338 for (auto& node : belowAppWindowNode_->children_) {
339 DestroyWindowNode(node, removedIds_);
340 }
341 for (auto& node : appWindowNode_->children_) {
342 DestroyWindowNode(node, removedIds_);
343 }
344 for (auto& node : aboveAppWindowNode_->children_) {
345 DestroyWindowNode(node, removedIds_);
346 }
347 return removedIds_;
348 }
349
FindRoot(WindowType type) const350 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
351 {
352 if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE) {
353 return appWindowNode_;
354 }
355 if (WindowHelper::IsBelowSystemWindow(type)) {
356 return belowAppWindowNode_;
357 }
358 if (WindowHelper::IsAboveSystemWindow(type)) {
359 return aboveAppWindowNode_;
360 }
361 return nullptr;
362 }
363
FindWindowNodeById(uint32_t id) const364 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
365 {
366 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
367 for (auto& rootNode : rootNodes) {
368 for (auto& node : rootNode->children_) {
369 if (node->GetWindowId() == id) {
370 return node;
371 }
372 for (auto& subNode : node->children_) {
373 if (subNode->GetWindowId() == id) {
374 return subNode;
375 }
376 }
377 }
378 }
379 return nullptr;
380 }
381
UpdateFocusStatus(uint32_t id,bool focused) const382 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused) const
383 {
384 auto node = FindWindowNodeById(id);
385 if (node == nullptr) {
386 WLOGFW("cannot find focused window id:%{public}d", id);
387 } else {
388 node->GetWindowToken()->UpdateFocusStatus(focused);
389 if (node->abilityToken_ == nullptr) {
390 WLOGFI("abilityToken is null, window : %{public}d", id);
391 }
392 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
393 node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
394 WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
395 focusChangeInfo, focused);
396 }
397 }
398
UpdateActiveStatus(uint32_t id,bool isActive) const399 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive) const
400 {
401 auto node = FindWindowNodeById(id);
402 if (node == nullptr) {
403 WLOGFE("cannot find active window id: %{public}d", id);
404 return;
405 }
406 node->GetWindowToken()->UpdateActiveStatus(isActive);
407 }
408
UpdateBrightness(uint32_t id,bool byRemoved)409 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
410 {
411 auto node = FindWindowNodeById(id);
412 if (node == nullptr) {
413 WLOGFE("cannot find active window id: %{public}d", id);
414 return;
415 }
416
417 if (!byRemoved) {
418 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
419 return;
420 }
421 }
422 WLOGFI("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
423 if (node->GetBrightness() == UNDEFINED_BRIGHTNESS) {
424 if (GetDisplayBrightness() != node->GetBrightness()) {
425 WLOGFI("adjust brightness with default value");
426 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
427 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
428 }
429 SetBrightnessWindow(INVALID_WINDOW_ID);
430 } else {
431 if (GetDisplayBrightness() != node->GetBrightness()) {
432 WLOGFI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
433 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
434 ToOverrideBrightness(node->GetBrightness()));
435 SetDisplayBrightness(node->GetBrightness());
436 }
437 SetBrightnessWindow(node->GetWindowId());
438 }
439 }
440
AssignZOrder()441 void WindowNodeContainer::AssignZOrder()
442 {
443 zOrder_ = 0;
444 WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
445 if (node->surfaceNode_ == nullptr) {
446 WLOGE("AssignZOrder: surfaceNode is nullptr, window Id:%{public}u", node->GetWindowId());
447 return false;
448 }
449 node->surfaceNode_->SetPositionZ(zOrder_);
450 ++zOrder_;
451 return false;
452 };
453 TraverseWindowTree(func, false);
454 }
455
SetFocusWindow(uint32_t windowId)456 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
457 {
458 if (focusedWindow_ == windowId) {
459 WLOGFI("focused window do not change, id: %{public}u", windowId);
460 return WMError::WM_DO_NOTHING;
461 }
462 UpdateFocusStatus(focusedWindow_, false);
463 focusedWindow_ = windowId;
464 sptr<WindowNode> node = FindWindowNodeById(windowId);
465 NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
466 UpdateFocusStatus(focusedWindow_, true);
467 return WMError::WM_OK;
468 }
469
GetFocusWindow() const470 uint32_t WindowNodeContainer::GetFocusWindow() const
471 {
472 return focusedWindow_;
473 }
474
SetActiveWindow(uint32_t windowId,bool byRemoved)475 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
476 {
477 if (activeWindow_ == windowId) {
478 WLOGFI("active window do not change, id: %{public}u", windowId);
479 return WMError::WM_DO_NOTHING;
480 }
481 UpdateActiveStatus(activeWindow_, false);
482 activeWindow_ = windowId;
483 UpdateActiveStatus(activeWindow_, true);
484 UpdateBrightness(activeWindow_, byRemoved);
485 return WMError::WM_OK;
486 }
487
SetDisplayBrightness(float brightness)488 void WindowNodeContainer::SetDisplayBrightness(float brightness)
489 {
490 displayBrightness_ = brightness;
491 }
492
GetDisplayBrightness() const493 float WindowNodeContainer::GetDisplayBrightness() const
494 {
495 return displayBrightness_;
496 }
497
SetBrightnessWindow(uint32_t windowId)498 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
499 {
500 brightnessWindow_ = windowId;
501 }
502
GetBrightnessWindow() const503 uint32_t WindowNodeContainer::GetBrightnessWindow() const
504 {
505 return brightnessWindow_;
506 }
507
ToOverrideBrightness(float brightness)508 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
509 {
510 return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
511 }
512
GetActiveWindow() const513 uint32_t WindowNodeContainer::GetActiveWindow() const
514 {
515 return activeWindow_;
516 }
517
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)518 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
519 {
520 if (requireLock && node->keepScreenLock_ == nullptr) {
521 // reset ipc identity
522 std::string identity = IPCSkeleton::ResetCallingIdentity();
523 node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
524 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
525 // set ipc identity to raw
526 IPCSkeleton::SetCallingIdentity(identity);
527 }
528 if (node->keepScreenLock_ == nullptr) {
529 return;
530 }
531 WLOGFI("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
532 ErrCode res;
533 // reset ipc identity
534 std::string identity = IPCSkeleton::ResetCallingIdentity();
535 if (requireLock) {
536 res = node->keepScreenLock_->Lock();
537 } else {
538 res = node->keepScreenLock_->UnLock();
539 }
540 // set ipc identity to raw
541 IPCSkeleton::SetCallingIdentity(identity);
542 if (res != ERR_OK) {
543 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
544 }
545 }
546
IsAboveSystemBarNode(sptr<WindowNode> node) const547 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
548 {
549 int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
550 if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
551 (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
552 return true;
553 }
554 return false;
555 }
556
IsFullImmersiveNode(sptr<WindowNode> node) const557 bool WindowNodeContainer::IsFullImmersiveNode(sptr<WindowNode> node) const
558 {
559 auto mode = node->GetWindowMode();
560 auto flags = node->GetWindowFlags();
561 return mode == WindowMode::WINDOW_MODE_FULLSCREEN &&
562 !(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
563 }
564
IsSplitImmersiveNode(sptr<WindowNode> node) const565 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
566 {
567 auto type = node->GetWindowType();
568 return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
569 }
570
GetExpectImmersiveProperty() const571 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
572 {
573 std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
574 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty() },
575 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
576 };
577
578 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
579 for (auto& node : rootNodes) {
580 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
581 auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
582 if (IsAboveSystemBarNode(*iter)) {
583 continue;
584 }
585 if (IsFullImmersiveNode(*iter)) {
586 WLOGFI("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
587 for (auto it : sysBarPropMap) {
588 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
589 }
590 return sysBarPropMap;
591 } else if (IsSplitImmersiveNode(*iter)) {
592 WLOGFI("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
593 for (auto it : sysBarPropMap) {
594 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
595 sysBarPropMap[it.first].enable_ = false;
596 }
597 return sysBarPropMap;
598 }
599 }
600 }
601
602 WLOGFI("No immersive window on top. Use default systembar Property");
603 return sysBarPropMap;
604 }
605
NotifyIfSystemBarTintChanged()606 void WindowNodeContainer::NotifyIfSystemBarTintChanged()
607 {
608 WM_FUNCTION_TRACE();
609 auto expectSystemBarProp = GetExpectImmersiveProperty();
610 SystemBarRegionTints tints;
611 for (auto it : sysBarTintMap_) {
612 auto expectProp = expectSystemBarProp.find(it.first)->second;
613 if (it.second.prop_ == expectProp) {
614 continue;
615 }
616 WLOGFI("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
617 static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
618 sysBarTintMap_[it.first].prop_ = expectProp;
619 sysBarTintMap_[it.first].type_ = it.first;
620 tints.emplace_back(sysBarTintMap_[it.first]);
621 }
622 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
623 }
624
NotifyIfSystemBarRegionChanged()625 void WindowNodeContainer::NotifyIfSystemBarRegionChanged()
626 {
627 WM_FUNCTION_TRACE();
628 SystemBarRegionTints tints;
629 for (auto it : sysBarTintMap_) { // split screen mode not support yet
630 auto sysNode = sysBarNodeMap_[it.first];
631 if (sysNode == nullptr || it.second.region_ == sysNode->GetLayoutRect()) {
632 continue;
633 }
634 auto& newRegion = sysNode->GetLayoutRect();
635 sysBarTintMap_[it.first].region_ = newRegion;
636 sysBarTintMap_[it.first].type_ = it.first;
637 tints.emplace_back(sysBarTintMap_[it.first]);
638 WLOGFI("system bar region update, type: %{public}d" \
639 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
640 static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
641 }
642 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
643 }
644
NotifySystemBarDismiss(sptr<WindowNode> & node)645 void WindowNodeContainer::NotifySystemBarDismiss(sptr<WindowNode>& node)
646 {
647 WM_FUNCTION_TRACE();
648 if (node == nullptr) {
649 WLOGE("could not find window");
650 return;
651 }
652 SystemBarRegionTints tints;
653 auto& sysBarPropMapNode = node->GetSystemBarProperty();
654 for (auto it : sysBarPropMapNode) {
655 it.second.enable_ = false;
656 node->SetSystemBarProperty(it.first, it.second);
657 WLOGFI("set system bar enable to false, id: %{public}u, type: %{public}d",
658 node->GetWindowId(), static_cast<int32_t>(it.first));
659 if (sysBarTintMap_[it.first].prop_.enable_) {
660 sysBarTintMap_[it.first].prop_.enable_ = false;
661 tints.emplace_back(sysBarTintMap_[it.first]);
662 WLOGFI("notify system bar dismiss, type: %{public}d", static_cast<int32_t>(it.first));
663 }
664 }
665 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
666 }
667
NotifySystemBarTints()668 void WindowNodeContainer::NotifySystemBarTints()
669 {
670 WM_FUNCTION_TRACE();
671 SystemBarRegionTints tints;
672 for (auto it : sysBarTintMap_) {
673 WLOGFD("system bar cur notify, type: %{public}d, " \
674 "visible: %{public}d, color: %{public}x | %{public}x, " \
675 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
676 static_cast<int32_t>(it.first),
677 sysBarTintMap_[it.first].region_.posX_, sysBarTintMap_[it.first].region_.posY_,
678 sysBarTintMap_[it.first].region_.width_, sysBarTintMap_[it.first].region_.height_,
679 sysBarTintMap_[it.first].prop_.enable_,
680 sysBarTintMap_[it.first].prop_.backgroundColor_, sysBarTintMap_[it.first].prop_.contentColor_);
681 tints.push_back(sysBarTintMap_[it.first]);
682 }
683 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints);
684 }
685
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const686 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
687 {
688 if (rootNode->children_.empty()) {
689 WLOGFE("root does not have any node");
690 return false;
691 }
692 auto node = *(rootNode->children_.rbegin());
693 if (node == nullptr) {
694 WLOGFE("window tree does not have any node");
695 return false;
696 }
697
698 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
699 if ((*iter)->priority_ > 0) {
700 return (*iter)->GetWindowId() == windowId;
701 } else {
702 break;
703 }
704 }
705 return node->GetWindowId() == windowId;
706 }
707
RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds,std::vector<sptr<WindowNode>> & windowNodes)708 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds,
709 std::vector<sptr<WindowNode>>& windowNodes)
710 {
711 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
712 uint32_t wid = (*iter)->GetWindowId();
713 auto idIter = std::find_if(orderedIds.begin(), orderedIds.end(),
714 [wid] (uint32_t id) { return id == wid; });
715 if (idIter != orderedIds.end()) {
716 orderedIds.erase(idIter);
717 sptr<WindowNode> node = *iter;
718 iter = windowNodes.erase(iter);
719 UpdateWindowTree(node);
720 WLOGFI("raise group window to top %{public}d", node->GetWindowId());
721 } else {
722 iter++;
723 }
724 }
725 return;
726 }
727
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)728 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
729 {
730 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
731 [windowId](sptr<WindowNode> node) {
732 return node->GetWindowId() == windowId;
733 });
734 // raise app node window to top
735 if (iter != windowNodes.end()) {
736 sptr<WindowNode> node = *iter;
737 windowNodes.erase(iter);
738 UpdateWindowTree(node);
739 WLOGFI("raise window to top %{public}d", node->GetWindowId());
740 }
741 }
742
NotifyAccessibilityWindowInfo(const sptr<WindowNode> & node,WindowUpdateType type) const743 void WindowNodeContainer::NotifyAccessibilityWindowInfo(const sptr<WindowNode>& node, WindowUpdateType type) const
744 {
745 if (node == nullptr) {
746 WLOGFE("window node is null");
747 return;
748 }
749 bool isNeedNotify = false;
750 switch (type) {
751 case WindowUpdateType::WINDOW_UPDATE_ADDED:
752 if (node->currentVisibility_) {
753 isNeedNotify = true;
754 }
755 break;
756 case WindowUpdateType::WINDOW_UPDATE_FOCUSED:
757 if (node->GetWindowId() == focusedWindow_) {
758 isNeedNotify = true;
759 }
760 break;
761 case WindowUpdateType::WINDOW_UPDATE_REMOVED:
762 isNeedNotify = true;
763 break;
764 default:
765 break;
766 }
767 if (isNeedNotify) {
768 std::vector<sptr<WindowInfo>> windowList;
769 GetWindowList(windowList);
770 sptr<WindowInfo> windowInfo = new WindowInfo();
771 windowInfo->wid_ = static_cast<int32_t>(node->GetWindowId());
772 windowInfo->windowRect_ = node->GetLayoutRect();
773 windowInfo->focused_ = node->GetWindowId() == focusedWindow_;
774 windowInfo->mode_ = node->GetWindowMode();
775 windowInfo->type_ = node->GetWindowType();
776 sptr<AccessibilityWindowInfo> accessibilityWindowInfo = new AccessibilityWindowInfo();
777 accessibilityWindowInfo->currentWindowInfo_ = windowInfo;
778 accessibilityWindowInfo->windowList_ = windowList;
779 WindowManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityWindowInfo, type);
780 }
781 }
782
GetWindowList(std::vector<sptr<WindowInfo>> & windowList) const783 void WindowNodeContainer::GetWindowList(std::vector<sptr<WindowInfo>>& windowList) const
784 {
785 std::vector<sptr<WindowNode>> windowNodes;
786 TraverseContainer(windowNodes);
787 for (auto node : windowNodes) {
788 sptr<WindowInfo> windowInfo = new WindowInfo();
789 windowInfo->wid_ = static_cast<int32_t>(node->GetWindowId());
790 windowInfo->windowRect_ = node->GetLayoutRect();
791 windowInfo->focused_ = node->GetWindowId() == focusedWindow_;
792 windowInfo->mode_ = node->GetWindowMode();
793 windowInfo->type_ = node->GetWindowType();
794 windowList.emplace_back(windowInfo);
795 }
796 }
797
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const798 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
799 {
800 for (auto& node : belowAppWindowNode_->children_) {
801 TraverseWindowNode(node, windowNodes);
802 }
803 for (auto& node : appWindowNode_->children_) {
804 TraverseWindowNode(node, windowNodes);
805 }
806 for (auto& node : aboveAppWindowNode_->children_) {
807 TraverseWindowNode(node, windowNodes);
808 }
809 std::reverse(windowNodes.begin(), windowNodes.end());
810 }
811
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const812 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
813 {
814 if (node == nullptr) {
815 return;
816 }
817 auto iter = node->children_.begin();
818 for (; iter < node->children_.end(); ++iter) {
819 if ((*iter)->priority_ < 0) {
820 windowNodes.emplace_back(*iter);
821 } else {
822 break;
823 }
824 }
825 windowNodes.emplace_back(node);
826 for (; iter < node->children_.end(); ++iter) {
827 windowNodes.emplace_back(*iter);
828 }
829 }
830
GetAvoidAreaByType(AvoidAreaType avoidAreaType)831 std::vector<Rect> WindowNodeContainer::GetAvoidAreaByType(AvoidAreaType avoidAreaType)
832 {
833 return avoidController_->GetAvoidAreaByType(avoidAreaType);
834 }
835
OnAvoidAreaChange(const std::vector<Rect> & avoidArea)836 void WindowNodeContainer::OnAvoidAreaChange(const std::vector<Rect>& avoidArea)
837 {
838 layoutPolicy_->UpdateDefaultFoatingRect();
839 for (auto& node : appWindowNode_->children_) {
840 if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && node->GetWindowToken() != nullptr) {
841 // notify client
842 node->GetWindowToken()->UpdateAvoidArea(avoidArea);
843 }
844 }
845 }
846
DumpScreenWindowTree()847 void WindowNodeContainer::DumpScreenWindowTree()
848 {
849 WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_);
850 WLOGFI("WindowName WinId Type Mode Flag ZOrd Orientation [ x y w h]");
851 uint32_t zOrder = zOrder_;
852 WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
853 Rect rect = node->GetLayoutRect();
854 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
855 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
856 WLOGI("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u %{public}4u %{public}4u " \
857 "%{public}11u [%{public}4d %{public}4d %{public}4u %{public}4u]",
858 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
859 node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
860 rect.posX_, rect.posY_, rect.width_, rect.height_);
861 return false;
862 };
863 TraverseWindowTree(func, true);
864 WLOGFI("-------- display %{public}" PRIu64" dump window info end ---------", displayId_);
865 }
866
GetScreenId() const867 uint64_t WindowNodeContainer::GetScreenId() const
868 {
869 return DisplayManagerServiceInner::GetInstance().GetRSScreenId(displayId_);
870 }
871
GetDisplayId() const872 DisplayId WindowNodeContainer::GetDisplayId() const
873 {
874 return displayId_;
875 }
876
GetDisplayRect() const877 Rect WindowNodeContainer::GetDisplayRect() const
878 {
879 return displayRect_;
880 }
881
GetDisplayLimitRect() const882 Rect WindowNodeContainer::GetDisplayLimitRect() const
883 {
884 return layoutPolicy_->GetDisplayLimitRect();
885 }
886
isVerticalDisplay() const887 bool WindowNodeContainer::isVerticalDisplay() const
888 {
889 return displayRect_.width_ < displayRect_.height_;
890 }
891
NotifyWindowStateChange(WindowState state,WindowStateChangeReason reason)892 void WindowNodeContainer::NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason)
893 {
894 switch (reason) {
895 case WindowStateChangeReason::KEYGUARD: {
896 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
897 TraverseAndUpdateWindowState(state, topPriority);
898 break;
899 }
900 default:
901 return;
902 }
903 }
904
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)905 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
906 {
907 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
908 for (auto& node : rootNodes) {
909 UpdateWindowState(node, topPriority, state);
910 }
911 }
912
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)913 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
914 {
915 if (node == nullptr) {
916 return;
917 }
918 if (node->parent_ != nullptr && node->currentVisibility_) {
919 if (node->priority_ < topPriority) {
920 node->GetWindowToken()->UpdateWindowState(state);
921 HandleKeepScreenOn(node, state);
922 }
923 }
924 for (auto& childNode : node->children_) {
925 UpdateWindowState(childNode, topPriority, state);
926 }
927 }
928
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)929 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
930 {
931 if (node == nullptr) {
932 WLOGFE("window is invalid");
933 return;
934 }
935 if (state == WindowState::STATE_FROZEN) {
936 HandleKeepScreenOn(node, false);
937 } else if (state == WindowState::STATE_UNFROZEN) {
938 HandleKeepScreenOn(node, node->IsKeepScreenOn());
939 } else {
940 // do nothing
941 }
942 }
943
FindDividerNode() const944 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
945 {
946 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
947 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
948 return *iter;
949 }
950 }
951 return nullptr;
952 }
953
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)954 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
955 {
956 sptr<WindowNode> deviderNode = nullptr;
957 sptr<WindowNode> primaryNode = nullptr;
958 sptr<WindowNode> secondaryNode = nullptr;
959 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && !pairedWindowMap_.empty()) {
960 deviderNode = node;
961 primaryNode = pairedWindowMap_.begin()->second.pairNode_;
962 secondaryNode = pairedWindowMap_[primaryNode->GetWindowId()].pairNode_;
963 std::vector<uint32_t> raiseNodeIds = {secondaryNode->GetWindowId(), primaryNode->GetWindowId()};
964 // raise primary and secondary window to top, keep raw zorder
965 RaiseOrderedWindowToTop(raiseNodeIds, appWindowNode_->children_);
966 // raise divider final, keep divider on top
967 RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_);
968 } else if (!pairedWindowMap_.empty()) {
969 deviderNode = FindDividerNode();
970 primaryNode = node;
971 secondaryNode = pairedWindowMap_.at(primaryNode->GetWindowId()).pairNode_;
972 RaiseWindowToTop(secondaryNode->GetWindowId(), appWindowNode_->children_);
973 RaiseWindowToTop(primaryNode->GetWindowId(), appWindowNode_->children_);
974 if (deviderNode != nullptr) {
975 // raise divider final, keep divider on top
976 RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_);
977 }
978 } else {
979 // raise self if not paired
980 RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_);
981 }
982 AssignZOrder();
983 return;
984 }
985
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)986 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
987 {
988 if (node == nullptr) {
989 return WMError::WM_ERROR_NULLPTR;
990 }
991 if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
992 WLOGFI("it is already top app window, id: %{public}d", node->GetWindowId());
993 return WMError::WM_ERROR_INVALID_TYPE;
994 }
995 if (WindowHelper::IsSubWindow(node->GetWindowType())) {
996 if (parentNode == nullptr) {
997 WLOGFE("window type is invalid");
998 return WMError::WM_ERROR_NULLPTR;
999 }
1000 RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1001 if (parentNode->IsSplitMode()) {
1002 RaiseSplitRelatedWindowToTop(parentNode);
1003 } else {
1004 RaiseWindowToTop(node->GetParentId(), parentNode->parent_->children_); // raise parent window
1005 }
1006 } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1007 if (node->IsSplitMode()) {
1008 RaiseSplitRelatedWindowToTop(node);
1009 } else {
1010 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1011 }
1012 } else {
1013 // do nothing
1014 }
1015 AssignZOrder();
1016 WLOGFI("RaiseZOrderForAppWindow finished");
1017 DumpScreenWindowTree();
1018 return WMError::WM_OK;
1019 }
1020
GetNextFocusableWindow(uint32_t windowId) const1021 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1022 {
1023 sptr<WindowNode> nextFocusableWindow;
1024 bool previousFocusedWindowFound = false;
1025 WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1026 sptr<WindowNode> node) {
1027 if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable()) {
1028 nextFocusableWindow = node;
1029 return true;
1030 }
1031 if (node->GetWindowId() == windowId) {
1032 previousFocusedWindowFound = true;
1033 }
1034 return false;
1035 };
1036 TraverseWindowTree(func, true);
1037 return nextFocusableWindow;
1038 }
1039
GetNextActiveWindow(uint32_t windowId) const1040 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1041 {
1042 auto currentNode = FindWindowNodeById(windowId);
1043 if (currentNode == nullptr) {
1044 WLOGFE("cannot find window id: %{public}u by tree", windowId);
1045 return nullptr;
1046 }
1047 WLOGFI("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1048 if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1049 for (auto& node : appWindowNode_->children_) {
1050 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1051 continue;
1052 }
1053 return node;
1054 }
1055 for (auto& node : belowAppWindowNode_->children_) {
1056 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1057 return node;
1058 }
1059 }
1060 } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1061 std::vector<sptr<WindowNode>> windowNodes;
1062 TraverseContainer(windowNodes);
1063 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1064 return node->GetWindowId() == windowId;
1065 });
1066 if (iter == windowNodes.end()) {
1067 WLOGFE("could not find this window");
1068 return nullptr;
1069 }
1070 int index = std::distance(windowNodes.begin(), iter);
1071 for (size_t i = index + 1; i < windowNodes.size(); i++) {
1072 if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1073 continue;
1074 }
1075 return windowNodes[i];
1076 }
1077 } else {
1078 // do nothing
1079 }
1080 WLOGFE("could not get next active window");
1081 return nullptr;
1082 }
1083
MinimizeAllAppWindows()1084 void WindowNodeContainer::MinimizeAllAppWindows()
1085 {
1086 WMError ret = MinimizeAppNodeExceptOptions(true);
1087 SwitchLayoutPolicy(WindowLayoutMode::CASCADE);
1088 if (ret != WMError::WM_OK) {
1089 WLOGFE("Minimize all app window failed");
1090 }
1091 return;
1092 }
1093
SendSplitScreenEvent(sptr<WindowNode> & node)1094 void WindowNodeContainer::SendSplitScreenEvent(sptr<WindowNode>& node)
1095 {
1096 // reset ipc identity
1097 std::string identity = IPCSkeleton::ResetCallingIdentity();
1098 AAFwk::Want want;
1099 want.SetAction(SPLIT_SCREEN_EVENT_NAME);
1100 std::string modeData = (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ? "Secondary" : "Primary";
1101 int32_t missionId = -1;
1102 AAFwk::AbilityManagerClient::GetInstance()->GetMissionIdByToken(node->abilityToken_, missionId);
1103 WLOGFI("split window missionId is: %{public}d", missionId);
1104 want.SetParam("windowMode", modeData);
1105 want.SetParam("missionId", missionId);
1106 EventFwk::CommonEventData commonEventData;
1107 commonEventData.SetWant(want);
1108 EventFwk::CommonEventManager::PublishCommonEvent(commonEventData);
1109 // set ipc identity to raw
1110 IPCSkeleton::SetCallingIdentity(identity);
1111 WLOGFI("send split sceen event finish.");
1112 }
1113
FindSplitPairNode(sptr<WindowNode> & triggerNode) const1114 sptr<WindowNode> WindowNodeContainer::FindSplitPairNode(sptr<WindowNode>& triggerNode) const
1115 {
1116 auto triggerMode = triggerNode->GetWindowMode();
1117 for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) {
1118 if ((*iter)->GetWindowId() == triggerNode->GetWindowId()) {
1119 continue;
1120 }
1121 // Find Top FullScreen main winodow or top paired split mode app main window
1122 if ((*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN ||
1123 (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
1124 (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) ||
1125 (triggerMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY &&
1126 (*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1127 WLOGFI("Find pair node mode is: %{public}d", static_cast<uint32_t>((*iter)->GetWindowMode()));
1128 return *iter;
1129 }
1130 }
1131 return nullptr;
1132 }
1133
MinimizeWindowFromAbility(const sptr<WindowNode> & node,bool fromUser)1134 void WindowNodeContainer::MinimizeWindowFromAbility(const sptr<WindowNode>& node, bool fromUser)
1135 {
1136 if (node->abilityToken_ == nullptr) {
1137 WLOGFW("Target abilityToken is nullptr, windowId:%{public}u", node->GetWindowId());
1138 return;
1139 }
1140 AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(node->abilityToken_, fromUser);
1141 }
1142
MinimizeAppNodeExceptOptions(bool fromUser,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1143 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(bool fromUser, const std::vector<uint32_t> &exceptionalIds,
1144 const std::vector<WindowMode> &exceptionalModes)
1145 {
1146 if (appWindowNode_->children_.empty()) {
1147 return WMError::WM_OK;
1148 }
1149 for (auto& appNode : appWindowNode_->children_) {
1150 // exclude exceptional window
1151 if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1152 std::find(exceptionalModes.begin(), exceptionalModes.end(),
1153 appNode->GetWindowMode()) != exceptionalModes.end() ||
1154 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1155 continue;
1156 }
1157 // minimize window
1158 WLOGFI("minimize window, windowId:%{public}u", appNode->GetWindowId());
1159 MinimizeWindowFromAbility(appNode, fromUser);
1160 }
1161 return WMError::WM_OK;
1162 }
1163
EnterSplitWindowMode(sptr<WindowNode> & node)1164 WMError WindowNodeContainer::EnterSplitWindowMode(sptr<WindowNode>& node)
1165 {
1166 WM_FUNCTION_TRACE();
1167 WLOGFI("Enter split window mode: %{public}d", node->GetWindowId());
1168 SwitchLayoutPolicy(WindowLayoutMode::CASCADE); // window split mode is belong to cascade
1169 auto pairNode = FindSplitPairNode(node);
1170 if (pairNode != nullptr) {
1171 WLOGFI("Window %{public}d find pair %{public}d", node->GetWindowId(), pairNode->GetWindowId());
1172 WMError ret = UpdateWindowPairInfo(node, pairNode);
1173 if (ret != WMError::WM_OK) {
1174 return ret;
1175 }
1176 SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_CREATE_DIVIDER, displayId_);
1177 std::vector<uint32_t> exceptionalIds;
1178 for (auto iter = pairedWindowMap_.begin(); iter != pairedWindowMap_.end(); iter++) {
1179 exceptionalIds.emplace_back(iter->first);
1180 }
1181 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1182 ret = MinimizeAppNodeExceptOptions(false, exceptionalIds, exceptionalModes);
1183 if (ret != WMError::WM_OK) {
1184 return ret;
1185 }
1186 } else {
1187 SendSplitScreenEvent(node);
1188 }
1189 return WMError::WM_OK;
1190 }
1191
ResetLayoutPolicy()1192 void WindowNodeContainer::ResetLayoutPolicy()
1193 {
1194 layoutPolicy_->Reset();
1195 }
1196
ExitSplitWindowMode(sptr<WindowNode> & node)1197 WMError WindowNodeContainer::ExitSplitWindowMode(sptr<WindowNode>& node)
1198 {
1199 WM_FUNCTION_TRACE();
1200 WLOGFI("exit split window mode %{public}d", node->GetWindowId());
1201 node->GetWindowProperty()->ResumeLastWindowMode();
1202 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1203 if (pairedWindowMap_.count(node->GetWindowId()) != 0) {
1204 auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_;
1205 pairNode->GetWindowProperty()->ResumeLastWindowMode();
1206 pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode());
1207 pairedWindowMap_.erase(pairNode->GetWindowId());
1208 pairedWindowMap_.erase(node->GetWindowId());
1209 WLOGFI("resume pair node mode, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", node->GetWindowId(),
1210 pairNode->GetWindowId(), node->GetWindowMode(), pairNode->GetWindowMode());
1211 }
1212 if (pairedWindowMap_.empty()) {
1213 WLOGFI("send destroy msg to divider, Id: %{public}d", node->GetWindowId());
1214 SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1215 }
1216 ResetLayoutPolicy();
1217 return WMError::WM_OK;
1218 }
1219
UpdateWindowPairInfo(sptr<WindowNode> & triggerNode,sptr<WindowNode> & pairNode)1220 WMError WindowNodeContainer::UpdateWindowPairInfo(sptr<WindowNode>& triggerNode, sptr<WindowNode>& pairNode)
1221 {
1222 float splitRatio = DEFAULT_SPLIT_RATIO;
1223 WindowMode triggerMode = triggerNode->GetWindowMode();
1224 WindowMode pairSrcMode = pairNode->GetWindowMode();
1225 if (pairSrcMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
1226 WindowMode pairDstMode = (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ?
1227 WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
1228 pairNode->SetWindowMode(pairDstMode);
1229 pairNode->GetWindowToken()->UpdateWindowMode(pairDstMode);
1230 WMError ret = UpdateWindowNode(pairNode, WindowUpdateReason::UPDATE_MODE);
1231 if (ret != WMError::WM_OK) {
1232 WLOGFE("Update window pair info failed");
1233 return ret;
1234 }
1235 WLOGFI("Pair FullScreen [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
1236 triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairDstMode, splitRatio);
1237 } else {
1238 if (pairedWindowMap_.count(pairNode->GetWindowId()) != 0) {
1239 WindowPairInfo info = pairedWindowMap_.at(pairNode->GetWindowId());
1240 auto prevPairNode = info.pairNode_;
1241 WLOGFI("%{public}d node is paird , pre paired id is %{public}d,",
1242 pairNode->GetWindowId(), prevPairNode->GetWindowId());
1243 prevPairNode->GetWindowProperty()->ResumeLastWindowMode();
1244 prevPairNode->GetWindowToken()->UpdateWindowMode(prevPairNode->GetWindowMode());
1245
1246 pairedWindowMap_.erase(prevPairNode->GetWindowId());
1247 pairedWindowMap_.erase(pairNode->GetWindowId());
1248
1249 splitRatio = info.splitRatio_;
1250 WLOGFI("Pair Split [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
1251 triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairSrcMode, splitRatio);
1252 } else {
1253 WLOGFI("%{public}d node is not paird", pairNode->GetWindowId());
1254 }
1255 }
1256 pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(triggerNode->GetWindowId(),
1257 {pairNode, splitRatio}));
1258 pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(pairNode->GetWindowId(),
1259 {triggerNode, 1 - splitRatio}));
1260 return WMError::WM_OK;
1261 }
1262
SwitchLayoutPolicy(WindowLayoutMode dstMode,bool reorder)1263 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder)
1264 {
1265 WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d",
1266 static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder));
1267 if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1268 WLOGFE("invalid layout mode");
1269 return WMError::WM_ERROR_INVALID_PARAM;
1270 }
1271 if (layoutMode_ != dstMode) {
1272 if (layoutMode_ == WindowLayoutMode::CASCADE && !pairedWindowMap_.empty()) {
1273 pairedWindowMap_.clear();
1274 SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1275 }
1276 layoutMode_ = dstMode;
1277 layoutPolicy_->Clean();
1278 layoutPolicy_ = layoutPolicys_[dstMode];
1279 layoutPolicy_->Launch();
1280 DumpScreenWindowTree();
1281 } else {
1282 WLOGFI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1283 }
1284 if (reorder) {
1285 if (!pairedWindowMap_.empty()) {
1286 // exit divider window when reorder
1287 pairedWindowMap_.clear();
1288 SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
1289 }
1290 layoutPolicy_->Reorder();
1291 DumpScreenWindowTree();
1292 }
1293 NotifyIfSystemBarTintChanged();
1294 return WMError::WM_OK;
1295 }
1296
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1297 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1298 {
1299 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1300 return;
1301 }
1302 auto iter = std::find_if(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(),
1303 [](sptr<WindowNode> node) {
1304 return node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD;
1305 });
1306 if (iter != aboveAppWindowNode_->children_.end()) {
1307 WLOGFI("raise input method float window priority.");
1308 node->priority_ = zorderPolicy_->GetWindowPriority(
1309 WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1310 }
1311 }
1312
ReZOrderShowWhenLockedWindows(const sptr<WindowNode> & node,bool up)1313 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(const sptr<WindowNode>& node, bool up)
1314 {
1315 WLOGFI("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1316 std::vector<sptr<WindowNode>> needReZOrderNodes;
1317 auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1318 auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1319 auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1320 zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1321
1322 for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1323 if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1324 needReZOrderNodes.emplace_back(*iter);
1325 iter = srcRoot->children_.erase(iter);
1326 } else {
1327 iter++;
1328 }
1329 }
1330
1331 for (auto& needReZOrderNode : needReZOrderNodes) {
1332 needReZOrderNode->priority_ = dstPriority;
1333 needReZOrderNode->parent_ = dstRoot;
1334 auto parentNode = needReZOrderNode->parent_;
1335 auto position = parentNode->children_.end();
1336 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1337 if ((*iter)->priority_ > needReZOrderNode->priority_) {
1338 position = iter;
1339 break;
1340 }
1341 }
1342 parentNode->children_.insert(position, needReZOrderNode);
1343 WLOGFI("ShowWhenLocked window %{public}u re-zorder when keyguard change %{public}u",
1344 needReZOrderNode->GetWindowId(), up);
1345 }
1346 }
1347
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1348 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1349 {
1350 // if keyguard window show, raise show when locked windows
1351 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1352 ReZOrderShowWhenLockedWindows(node, true);
1353 return;
1354 }
1355
1356 // if show when locked window show, raise itself when exist keyguard
1357 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
1358 return;
1359 }
1360
1361 auto iter = std::find_if(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(),
1362 [](sptr<WindowNode> node) {
1363 return node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD;
1364 });
1365 if (iter != aboveAppWindowNode_->children_.end()) {
1366 WLOGFI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1367 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1368 node->parent_ = aboveAppWindowNode_;
1369 }
1370 }
1371
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1372 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1373 {
1374 // if keyguard window hide, drop show when locked windows
1375 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1376 ReZOrderShowWhenLockedWindows(node, false);
1377 AssignZOrder();
1378 }
1379 }
1380
MoveWindowNode(sptr<WindowNodeContainer> & container)1381 void WindowNodeContainer::MoveWindowNode(sptr<WindowNodeContainer>& container)
1382 {
1383 DisplayId from = container->GetDisplayId();
1384 WLOGFI("disconnect expand display: %{public}" PRId64 ", move window node to display: "
1385 "%{public}" PRId64 "", from, displayId_);
1386 for (auto& node : container->aboveAppWindowNode_->children_) {
1387 WLOGFI("aboveAppWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1388 aboveAppWindowNode_->children_.push_back(node);
1389 layoutPolicy_->AddWindowNode(node);
1390 }
1391 for (auto& node : container->appWindowNode_->children_) {
1392 WLOGFI("appWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1393 appWindowNode_->children_.push_back(node);
1394 layoutPolicy_->AddWindowNode(node);
1395 }
1396 for (auto& node : container->belowAppWindowNode_->children_) {
1397 WLOGFI("belowAppWindowNode_: move windowNode: %{public}d", node->GetWindowId());
1398 belowAppWindowNode_->children_.push_back(node);
1399 layoutPolicy_->AddWindowNode(node);
1400 }
1401 }
1402
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1403 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1404 {
1405 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1406 if (isFromTopToBottom) {
1407 std::reverse(rootNodes.begin(), rootNodes.end());
1408 }
1409
1410 for (auto& node : rootNodes) {
1411 if (isFromTopToBottom) {
1412 for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1413 if (TraverseFromTopToBottom(*iter, func)) {
1414 return;
1415 }
1416 }
1417 } else {
1418 for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1419 if (TraverseFromBottomToTop(*iter, func)) {
1420 return;
1421 }
1422 }
1423 }
1424 }
1425 }
1426
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1427 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1428 {
1429 if (node == nullptr) {
1430 return false;
1431 }
1432 auto iterBegin = node->children_.rbegin();
1433 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1434 if ((*iterBegin)->priority_ <= 0) {
1435 break;
1436 }
1437 if (func(*iterBegin)) {
1438 return true;
1439 }
1440 }
1441 if (func(node)) {
1442 return true;
1443 }
1444 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1445 if (func(*iterBegin)) {
1446 return true;
1447 }
1448 }
1449 return false;
1450 }
1451
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1452 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1453 {
1454 if (node == nullptr) {
1455 return false;
1456 }
1457 auto iterBegin = node->children_.begin();
1458 for (; iterBegin != node->children_.end(); ++iterBegin) {
1459 if ((*iterBegin)->priority_ >= 0) {
1460 break;
1461 }
1462 if (func(*iterBegin)) {
1463 return true;
1464 }
1465 }
1466 if (func(node)) {
1467 return true;
1468 }
1469 for (; iterBegin != node->children_.end(); ++iterBegin) {
1470 if (func(*iterBegin)) {
1471 return true;
1472 }
1473 }
1474 return false;
1475 }
1476
UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>> & infos)1477 void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>>& infos)
1478 {
1479 currentCoveredArea_.clear();
1480 WindowNodeOperationFunc func = [this, &infos](sptr<WindowNode> node) {
1481 if (node == nullptr) {
1482 return false;
1483 }
1484 Rect layoutRect = node->GetLayoutRect();
1485 int32_t nodeX = std::max(0, layoutRect.posX_);
1486 int32_t nodeY = std::max(0, layoutRect.posY_);
1487 int32_t nodeXEnd = std::min(displayRect_.posX_ + static_cast<int32_t>(displayRect_.width_),
1488 layoutRect.posX_ + static_cast<int32_t>(layoutRect.width_));
1489 int32_t nodeYEnd = std::min(displayRect_.posY_ + static_cast<int32_t>(displayRect_.height_),
1490 layoutRect.posY_ + static_cast<int32_t>(layoutRect.height_));
1491
1492 Rect rectInDisplay = {nodeX, nodeY,
1493 static_cast<uint32_t>(nodeXEnd - nodeX), static_cast<uint32_t>(nodeYEnd - nodeY)};
1494 bool isCovered = false;
1495 for (auto& rect : currentCoveredArea_) {
1496 if (rectInDisplay.IsInsideOf(rect)) {
1497 isCovered = true;
1498 WLOGD("UpdateWindowVisibilityInfos: find covered window:%{public}u", node->GetWindowId());
1499 break;
1500 }
1501 }
1502 if (!isCovered) {
1503 currentCoveredArea_.emplace_back(rectInDisplay);
1504 }
1505 if (isCovered != node->isCovered_) {
1506 node->isCovered_ = isCovered;
1507 infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
1508 node->GetCallingUid(), !isCovered));
1509 WLOGD("UpdateWindowVisibilityInfos: covered status changed window:%{public}u, covered:%{public}d",
1510 node->GetWindowId(), isCovered);
1511 }
1512 return false;
1513 };
1514 TraverseWindowTree(func, true);
1515 WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(infos);
1516 }
1517
GetVirtualPixelRatio() const1518 float WindowNodeContainer::GetVirtualPixelRatio() const
1519 {
1520 return layoutPolicy_->GetVirtualPixelRatio();
1521 }
1522
ReadIsWindowAnimationEnabledProperty()1523 bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty()
1524 {
1525 if (access(DISABLE_WINDOW_ANIMATION_PATH, F_OK) == 0) {
1526 return false;
1527 }
1528 return true;
1529 }
1530 } // namespace Rosen
1531 } // namespace OHOS
1532