1 /*
2 * Copyright (c) 2021-2022 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 <cmath>
22 #include <ctime>
23 #include <display_power_mgr_client.h>
24 #include <hitrace_meter.h>
25 #include <limits>
26 #include <power_mgr_client.h>
27 #include <transaction/rs_interfaces.h>
28 #include <transaction/rs_transaction.h>
29
30 #include "common_event_manager.h"
31 #include "dm_common.h"
32 #include "remote_animation.h"
33 #include "starting_window.h"
34 #include "window_helper.h"
35 #include "window_inner_manager.h"
36 #include "window_layout_policy_cascade.h"
37 #include "window_layout_policy_tile.h"
38 #include "window_manager_agent_controller.h"
39 #include "window_manager_hilog.h"
40 #include "window_manager_service.h"
41 #include "wm_common.h"
42 #include "wm_common_inner.h"
43
44 namespace OHOS {
45 namespace Rosen {
46 namespace {
47 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowNodeContainer"};
48 constexpr int WINDOW_NAME_MAX_LENGTH = 10;
49 constexpr uint32_t MAX_BRIGHTNESS = 255;
50 constexpr uint32_t SPLIT_WINDOWS_CNT = 2;
51 constexpr uint32_t EXIT_SPLIT_POINTS_NUMBER = 2;
52 constexpr int UID_TRANSFROM_DIVISOR = 200000;
53 constexpr int UID_MIN = 100;
54 }
55 AnimationConfig WindowNodeContainer::animationConfig_;
56
WindowNodeContainer(const sptr<DisplayInfo> & displayInfo,ScreenId displayGroupId)57 WindowNodeContainer::WindowNodeContainer(const sptr<DisplayInfo>& displayInfo, ScreenId displayGroupId)
58 {
59 DisplayId displayId = displayInfo->GetDisplayId();
60
61 // create and displayGroupInfo and displayGroupController
62 displayGroupInfo_ = new DisplayGroupInfo(displayGroupId, displayInfo);
63 displayGroupController_ = new DisplayGroupController(this, displayGroupInfo_);
64 displayGroupController_->InitNewDisplay(displayId);
65
66 // init layout policy
67 layoutPolicies_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(displayGroupInfo_,
68 displayGroupController_->displayGroupWindowTree_);
69 layoutPolicies_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(displayGroupInfo_,
70 displayGroupController_->displayGroupWindowTree_);
71 layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE];
72 layoutPolicy_->Launch();
73
74 Rect initalDividerRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId);
75 displayGroupController_->SetDividerRect(displayId, initalDividerRect);
76 // init avoidAreaController
77 avoidController_ = new AvoidAreaController(focusedWindow_);
78 }
79
~WindowNodeContainer()80 WindowNodeContainer::~WindowNodeContainer()
81 {
82 Destroy();
83 }
84
GetWindowCountByType(WindowType windowType)85 uint32_t WindowNodeContainer::GetWindowCountByType(WindowType windowType)
86 {
87 uint32_t windowNumber = 0;
88 auto counter = [&windowNumber, &windowType](sptr<WindowNode>& windowNode) {
89 if (windowNode->GetWindowType() == windowType && !windowNode->startingWindowShown_) ++windowNumber;
90 };
91 std::for_each(belowAppWindowNode_->children_.begin(), belowAppWindowNode_->children_.end(), counter);
92 std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
93 std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
94 return windowNumber;
95 }
96
AddWindowNodeOnWindowTree(sptr<WindowNode> & node,const sptr<WindowNode> & parentNode)97 WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, const sptr<WindowNode>& parentNode)
98 {
99 sptr<WindowNode> root = FindRoot(node->GetWindowType());
100 if (root == nullptr && !(WindowHelper::IsSystemSubWindow(node->GetWindowType()) &&
101 parentNode != nullptr)) {
102 WLOGFE("root is nullptr!");
103 return WMError::WM_ERROR_NULLPTR;
104 }
105 node->requestedVisibility_ = true;
106 if (parentNode != nullptr) { // subwindow
107 if (WindowHelper::IsSystemSubWindow(node->GetWindowType()) ||
108 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
109 if (WindowHelper::IsSubWindow(parentNode->GetWindowType()) ||
110 WindowHelper::IsSystemSubWindow(parentNode->GetWindowType()) ||
111 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT ||
112 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
113 // some times, dialog is a child window, so exclude
114 WLOGFE("the parent of window cannot be any sub window");
115 return WMError::WM_ERROR_INVALID_PARAM;
116 }
117 } else {
118 if (parentNode->parent_ != root &&
119 !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
120 (parentNode->parent_ == aboveAppWindowNode_))) {
121 WLOGFE("window type and parent window not match \
122 or try to add subwindow to subwindow, which is forbidden");
123 return WMError::WM_ERROR_INVALID_PARAM;
124 }
125 }
126 node->currentVisibility_ = parentNode->currentVisibility_;
127 node->parent_ = parentNode;
128 } else { // mainwindow
129 node->parent_ = root;
130 node->currentVisibility_ = true;
131 for (auto& child : node->children_) {
132 child->currentVisibility_ = child->requestedVisibility_;
133 }
134 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
135 displayGroupController_->sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node;
136 }
137 }
138 return WMError::WM_OK;
139 }
140
ShowStartingWindow(sptr<WindowNode> & node)141 WMError WindowNodeContainer::ShowStartingWindow(sptr<WindowNode>& node)
142 {
143 if (node->currentVisibility_) {
144 WLOGFE("current window is visible, windowId: %{public}u", node->GetWindowId());
145 return WMError::WM_ERROR_INVALID_OPERATION;
146 }
147
148 WMError res = AddWindowNodeOnWindowTree(node, nullptr);
149 if (res != WMError::WM_OK) {
150 return res;
151 }
152 UpdateWindowTree(node);
153 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
154 StartingWindow::AddNodeOnRSTree(node, animationConfig_, layoutPolicy_->IsMultiDisplay());
155 AssignZOrder();
156 layoutPolicy_->AddWindowNode(node);
157 WLOGFD("ShowStartingWindow windowId: %{public}u end", node->GetWindowId());
158 return WMError::WM_OK;
159 }
160
IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode> & node)161 WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode>& node)
162 {
163 if (layoutMode_ == WindowLayoutMode::TILE &&
164 !layoutPolicy_->IsTileRectSatisfiedWithSizeLimits(node)) {
165 WLOGFE("layoutMode is tile, default rect is not satisfied with size limits of window, windowId: %{public}u",
166 node->GetWindowId());
167 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
168 }
169 return WMError::WM_OK;
170 }
171
GetAnimationConfigRef()172 AnimationConfig& WindowNodeContainer::GetAnimationConfigRef()
173 {
174 return animationConfig_;
175 }
176
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)177 void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
178 {
179 if (afterAnimation) {
180 layoutPolicy_->AddWindowNode(node);
181 return;
182 }
183 WLOGFD("AddWindowNode windowId:%{public}u, name:%{public}s currState:%{public}u",
184 node->GetWindowId(), node->GetWindowName().c_str(),
185 static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
186 if (WindowHelper::IsMainWindow(node->GetWindowType()) &&
187 RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
188 node->stateMachine_.IsShowAnimationPlaying()) {
189 // for first frame callback
190 auto winRect = node->GetWindowRect();
191 if (node->surfaceNode_) {
192 node->surfaceNode_->SetBounds(0, 0, winRect.width_, winRect.height_);
193 WLOGFD("notify client and SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
194 node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
195 layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, WindowSizeChangeReason::UNDEFINED);
196 }
197 } else {
198 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
199 WindowHelper::IsSystemWindow(node->GetWindowType())) {
200 node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW);
201 }
202 layoutPolicy_->AddWindowNode(node);
203 }
204 }
205
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode,bool afterAnimation)206 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, bool afterAnimation)
207 {
208 if (!node->startingWindowShown_) { // window except main Window
209 WMError res = AddWindowNodeOnWindowTree(node, parentNode);
210 if (res != WMError::WM_OK) {
211 return res;
212 }
213 UpdateWindowTree(node);
214 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
215 // add node on RSTree
216 for (auto& displayId : node->GetShowingDisplays()) {
217 AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ADDED,
218 node->isPlayAnimationShow_);
219 }
220 } else { // only main app window has starting window
221 node->isPlayAnimationShow_ = false;
222 node->startingWindowShown_ = false;
223 AddAppSurfaceNodeOnRSTree(node);
224 ReZOrderShowWhenLockedWindowIfNeeded(node);
225 RaiseZOrderForAppWindow(node, parentNode);
226 }
227 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
228 if (windowPair == nullptr) {
229 WLOGFE("Window pair is nullptr");
230 return WMError::WM_ERROR_NULLPTR;
231 }
232 windowPair->UpdateIfSplitRelated(node);
233 if (node->IsSplitMode()) {
234 // raise the z-order of window pair
235 RaiseSplitRelatedWindowToTop(node);
236 }
237 AssignZOrder();
238 LayoutWhenAddWindowNode(node, afterAnimation);
239 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
240 DumpScreenWindowTree();
241 UpdateCameraFloatWindowStatus(node, true);
242 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
243 backupWindowIds_.clear();
244 }
245
246 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
247 isScreenLocked_ = true;
248 SetBelowScreenlockVisible(node, false);
249 }
250 if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
251 RemoteAnimation::NotifyAnimationUpdateWallpaper(node);
252 }
253 WLOGFD("AddWindowNode windowId: %{public}u end", node->GetWindowId());
254 RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
255 return WMError::WM_OK;
256 }
257
UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode> & node,const std::vector<DisplayId> & lastShowingDisplays)258 void WindowNodeContainer::UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode>& node,
259 const std::vector<DisplayId>& lastShowingDisplays)
260 {
261 if (!layoutPolicy_->IsMultiDisplay()) {
262 return;
263 }
264
265 // Update RSTree
266 auto curShowingDisplays = node->GetShowingDisplays();
267 for (auto& displayId : lastShowingDisplays) {
268 if (std::find(curShowingDisplays.begin(), curShowingDisplays.end(), displayId) == curShowingDisplays.end()) {
269 RemoveNodeFromRSTree(node, displayId, *(curShowingDisplays.begin()),
270 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
271 WLOGFD("remove from RSTree : %{public}" PRIu64"", displayId);
272 }
273 }
274
275 for (auto& displayId : curShowingDisplays) {
276 if (std::find(lastShowingDisplays.begin(), lastShowingDisplays.end(), displayId) == lastShowingDisplays.end()) {
277 AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
278 WLOGFD("add on RSTree : %{public}" PRIu64"", displayId);
279 }
280 }
281 }
282
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)283 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
284 {
285 // Get last displayId and last showing displays before layout
286 auto lastShowingDisplays = node->GetShowingDisplays();
287
288 // PreProcess window node and layout node
289 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
290 if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
291 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId());
292 }
293 layoutPolicy_->UpdateWindowNode(node);
294 displayGroupController_->PostProcessWindowNode(node);
295 // Get current displayId and showing displays, update RSTree and displayGroupWindowTree
296 UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays);
297 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_UPDATE);
298 DumpScreenWindowTree();
299 WLOGFD("UpdateWindowNode windowId: %{public}u end", node->GetWindowId());
300 return WMError::WM_OK;
301 }
302
RemoveWindowNodeFromWindowTree(sptr<WindowNode> & node)303 void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr<WindowNode>& node)
304 {
305 // remove this node from parent
306 auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
307 if (iter != node->parent_->children_.end()) {
308 node->parent_->children_.erase(iter);
309 } else {
310 WLOGFE("can't find this node in parent");
311 }
312 node->parent_ = nullptr;
313 }
314
RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)315 void WindowNodeContainer::RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
316 {
317 if (fromAnimation || (RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
318 node->stateMachine_.IsHideAnimationPlaying())) {
319 WLOGFD("not remove from rs tree id:%{public}u", node->GetWindowId());
320 return;
321 }
322 // When RemoteAnimation exists, remove node from rs tree after animation
323 WLOGFD("remove from rs tree id:%{public}u, node->isPlayAnimationHide_:%{public}u", node->GetWindowId(),
324 static_cast<uint32_t>(node->isPlayAnimationHide_));
325 // subwindow or no remote animation also exit with animation
326 for (auto& displayId : node->GetShowingDisplays()) {
327 RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_REMOVED,
328 node->isPlayAnimationHide_);
329 }
330 }
331
SetSurfaceNodeVisible(sptr<WindowNode> & node,int32_t topPriority,bool visible)332 void WindowNodeContainer::SetSurfaceNodeVisible(sptr<WindowNode>& node, int32_t topPriority, bool visible)
333 {
334 if (node == nullptr) {
335 return;
336 }
337 if (node->parent_ != nullptr && node->currentVisibility_) {
338 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
339 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
340 auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
341 if (surfaceNode) {
342 surfaceNode->SetVisible(visible);
343 }
344 }
345 }
346 for (auto& childNode : node->children_) {
347 SetSurfaceNodeVisible(childNode, topPriority, visible);
348 }
349 }
350
SetBelowScreenlockVisible(sptr<WindowNode> & node,bool visible)351 void WindowNodeContainer::SetBelowScreenlockVisible(sptr<WindowNode>& node, bool visible)
352 {
353 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
354 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
355 for (auto& node : rootNodes) {
356 SetSurfaceNodeVisible(node, topPriority, visible);
357 }
358 }
359
RemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)360 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
361 {
362 if (node == nullptr) {
363 WLOGFE("window node or surface node is nullptr, invalid");
364 return WMError::WM_ERROR_DESTROYED_OBJECT;
365 }
366 if (node->parent_ == nullptr) {
367 WLOGFW("can't find parent of this node");
368 } else {
369 RemoveWindowNodeFromWindowTree(node);
370 }
371
372 node->requestedVisibility_ = false;
373 node->currentVisibility_ = false;
374 RemoveFromRsTreeWhenRemoveWindowNode(node, fromAnimation);
375 node->isPlayAnimationHide_ = false;
376 displayGroupController_->UpdateDisplayGroupWindowTree();
377
378 layoutPolicy_->RemoveWindowNode(node);
379 WindowMode lastMode = node->GetWindowMode();
380 if (HandleRemoveWindow(node) != WMError::WM_OK) {
381 return WMError::WM_ERROR_NULLPTR;
382 }
383 if (!WindowHelper::IsFloatingWindow(lastMode)) {
384 NotifyDockWindowStateChanged(node, true);
385 }
386 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_REMOVE);
387 DumpScreenWindowTree();
388 UpdateCameraFloatWindowStatus(node, false);
389 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
390 isScreenLocked_ = false;
391 SetBelowScreenlockVisible(node, true);
392 }
393 if (node->GetWindowType() == WindowType::WINDOW_TYPE_BOOT_ANIMATION) {
394 DisplayManagerServiceInner::GetInstance().SetGravitySensorSubscriptionEnabled();
395 }
396 WLOGFD("RemoveWindowNode windowId: %{public}u end", node->GetWindowId());
397 RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
398 return WMError::WM_OK;
399 }
400
GetAppWindowNum()401 uint32_t WindowNodeContainer::GetAppWindowNum()
402 {
403 uint32_t num = 0;
404 for (auto& child : appWindowNode_->children_) {
405 if (WindowHelper::IsAppWindow(child->GetWindowType())) {
406 num++;
407 }
408 }
409 return num;
410 }
411
HandleRemoveWindow(sptr<WindowNode> & node)412 WMError WindowNodeContainer::HandleRemoveWindow(sptr<WindowNode>& node)
413 {
414 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
415 if (windowPair == nullptr) {
416 WLOGFE("Window pair is nullptr");
417 return WMError::WM_ERROR_NULLPTR;
418 }
419 windowPair->HandleRemoveWindow(node);
420 auto dividerWindow = windowPair->GetDividerWindow();
421 auto type = node->GetWindowType();
422 if ((type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) &&
423 dividerWindow != nullptr) {
424 UpdateWindowNode(dividerWindow, WindowUpdateReason::UPDATE_RECT);
425 }
426 return WMError::WM_OK;
427 }
428
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)429 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
430 {
431 WMError ret = RemoveWindowNode(node);
432 if (ret != WMError::WM_OK) {
433 WLOGFE("RemoveWindowNode failed");
434 return ret;
435 }
436 StartingWindow::ReleaseStartWinSurfaceNode(node);
437 node->surfaceNode_ = nullptr;
438 windowIds.push_back(node->GetWindowId());
439 for (auto& child : node->children_) { // destroy sub window if exists
440 windowIds.push_back(child->GetWindowId());
441 child->parent_ = nullptr;
442 if (child->surfaceNode_ != nullptr) {
443 WLOGFD("child surfaceNode set nullptr");
444 child->surfaceNode_ = nullptr;
445 }
446 }
447
448 // clear vector cache completely, swap with empty vector
449 auto emptyVector = std::vector<sptr<WindowNode>>();
450 node->children_.swap(emptyVector);
451 if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
452 RemoteAnimation::NotifyAnimationUpdateWallpaper(nullptr);
453 }
454
455 UpdateAvoidAreaListener(node, false);
456 WLOGFD("DestroyWindowNode windowId: %{public}u end", node->GetWindowId());
457 return WMError::WM_OK;
458 }
459
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)460 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
461 {
462 if (!node->GetWindowToken()) {
463 WLOGFE("windowToken is null");
464 return;
465 }
466 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
467 for (auto& childNode : appWindowNode_->children_) {
468 if (childNode->IsSplitMode()) {
469 layoutPolicy_->UpdateClientRect(childNode->GetWindowRect(), childNode, reason);
470 childNode->ResetWindowSizeChangeReason();
471 WLOGFD("Notify split window that the drag action is start or end, windowId: %{public}d, "
472 "reason: %{public}u", childNode->GetWindowId(), reason);
473 }
474 }
475 } else {
476 layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, reason);
477 node->ResetWindowSizeChangeReason();
478 WLOGFD("Notify window that the drag action is start or end, windowId: %{public}d, "
479 "reason: %{public}u", node->GetWindowId(), reason);
480 }
481 }
482
UpdateWindowTree(sptr<WindowNode> & node)483 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
484 {
485 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
486 node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
487 RaiseInputMethodWindowPriorityIfNeeded(node);
488 RaiseShowWhenLockedWindowIfNeeded(node);
489 auto parentNode = node->parent_;
490 if (parentNode == nullptr) {
491 WLOGFD("Current window node has no parent: %{public}u", node->GetWindowId());
492 return;
493 }
494 auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
495 if (iter != parentNode->children_.end()) {
496 WLOGFD("node %{public}u is already on window tree, no need to update!", node->GetWindowId());
497 return;
498 }
499 auto position = parentNode->children_.end();
500 int splitWindowCnt = 0;
501 for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
502 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
503 position = child;
504 break;
505 }
506 if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
507 splitWindowCnt++;
508 }
509 if ((*child)->priority_ > node->priority_) {
510 position = child;
511 break;
512 }
513 }
514 parentNode->children_.insert(position, node);
515 }
516
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)517 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
518 {
519 /*
520 * App main window must has starting window, and show after starting window
521 * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
522 * Just need add appSurface Node as child of leashWindowSurfaceNode
523 */
524 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree");
525 if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
526 WLOGFE("id:%{public}u not main app window but has start window", node->GetWindowId());
527 return false;
528 }
529 if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
530 WLOGFE("id:%{public}u leashWinSurfaceNode or surfaceNode is null but has start window!", node->GetWindowId());
531 return false;
532 }
533 WLOGFD("AddAppSurfaceNodeOnRSTree windowId: %{public}d", node->GetWindowId());
534 if (!node->currentVisibility_) {
535 WLOGFD("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
536 return false;
537 }
538 node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
539 return true;
540 }
541
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)542 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
543 WindowUpdateType type, bool animationPlayed)
544 {
545 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
546 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
547 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
548 WLOGFD("not need to update RSTree");
549 return true;
550 }
551 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
552 WLOGFD("AddNodeOnRSTree windowId: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
553 "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
554 node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
555 auto updateRSTreeFunc = [&]() {
556 auto& dms = DisplayManagerServiceInner::GetInstance();
557 if (!node->currentVisibility_) {
558 WLOGFD("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
559 return;
560 }
561 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
562 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
563 for (auto& child : node->children_) {
564 if (child->currentVisibility_) {
565 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
566 }
567 }
568 };
569
570 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
571 updateRSTreeFunc();
572 return true;
573 }
574
575 if (node->EnableDefaultAnimation(animationPlayed)) {
576 WLOGFD("add window with animation");
577 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
578 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
579 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
580 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
581 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
582 !animationPlayed) { // add keyboard with animation
583 ProcessInputMethodWindowAddAnimation(node, updateRSTreeFunc);
584 } else {
585 WLOGFD("add window without animation");
586 updateRSTreeFunc();
587 }
588 return true;
589 }
590
ProcessInputMethodWindowAddAnimation(sptr<WindowNode> & node,std::function<void ()> updateRSTreeFunc)591 void WindowNodeContainer::ProcessInputMethodWindowAddAnimation(sptr<WindowNode>& node,
592 std::function<void()> updateRSTreeFunc)
593 {
594 static sptr<WindowNode> imeNode = nullptr;
595 if (imeNode == node && imeNode != nullptr && imeNode->surfaceNode_ != nullptr) {
596 WLOGFD("imeNode SetAppFreeze(true)");
597 imeNode->surfaceNode_->SetAppFreeze(true);
598 }
599 sptr<WindowNode> launcherNode = nullptr;
600 for (auto& windowNode : belowAppWindowNode_->children_) {
601 if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
602 launcherNode = windowNode;
603 break;
604 }
605 }
606 if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
607 WLOGFD("launcherNode SetAppFreeze(true)");
608 launcherNode->surfaceNode_->SetAppFreeze(true);
609 }
610 auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationIn_;
611 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc,
612 [ime = imeNode, node, launcherNode]() {
613 if (ime == node && ime != nullptr && ime->surfaceNode_ != nullptr) {
614 WLOGFD("imeNode SetAppFreeze(false)");
615 ime->surfaceNode_->SetAppFreeze(false);
616 }
617 if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
618 WLOGFD("launcherNode SetAppFreeze(false)");
619 launcherNode->surfaceNode_->SetAppFreeze(false);
620 }
621 auto transactionProxy = RSTransactionProxy::GetInstance();
622 if (transactionProxy != nullptr) {
623 transactionProxy->FlushImplicitTransaction();
624 }
625 });
626 imeNode = node;
627 }
628
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)629 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
630 WindowUpdateType type, bool animationPlayed)
631 {
632 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
633 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
634 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
635 WLOGFD("not need to update RSTree");
636 return true;
637 }
638 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
639 WLOGFD("RemoveNodeFromRSTree windowId: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
640 "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
641 node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
642 auto updateRSTreeFunc = [&]() {
643 auto& dms = DisplayManagerServiceInner::GetInstance();
644 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
645 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
646 for (auto& child : node->children_) {
647 if (child->currentVisibility_) {
648 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
649 }
650 }
651 };
652
653 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
654 updateRSTreeFunc();
655 return true;
656 }
657
658 if (node->EnableDefaultAnimation(animationPlayed)) {
659 WLOGFD("remove window with animation");
660 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
661 if (node->surfaceNode_) {
662 node->surfaceNode_->SetAppFreeze(true);
663 }
664 wptr<WindowNode> weakNode(node);
665 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
666 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
667 auto weakWindow = weakNode.promote();
668 if (weakWindow && weakWindow->surfaceNode_) {
669 weakWindow->surfaceNode_->SetAppFreeze(false);
670 }
671 });
672 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
673 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
674 !animationPlayed) { // remove keyboard with animation
675 auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationOut_;
676 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc);
677 } else {
678 WLOGFD("remove window without animation");
679 updateRSTreeFunc();
680 }
681 return true;
682 }
683
Destroy()684 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
685 {
686 // clear vector cache completely, swap with empty vector
687 auto emptyVector = std::vector<uint32_t>();
688 removedIds_.swap(emptyVector);
689 for (auto& node : belowAppWindowNode_->children_) {
690 DestroyWindowNode(node, removedIds_);
691 }
692 for (auto& node : appWindowNode_->children_) {
693 DestroyWindowNode(node, removedIds_);
694 }
695 for (auto& node : aboveAppWindowNode_->children_) {
696 DestroyWindowNode(node, removedIds_);
697 }
698 return removedIds_;
699 }
700
FindRoot(WindowType type) const701 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
702 {
703 if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
704 type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
705 type == WindowType::WINDOW_TYPE_DIALOG) {
706 return appWindowNode_;
707 }
708 if (WindowHelper::IsBelowSystemWindow(type)) {
709 return belowAppWindowNode_;
710 }
711 if (WindowHelper::IsAboveSystemWindow(type)) {
712 return aboveAppWindowNode_;
713 }
714 return nullptr;
715 }
716
FindWindowNodeById(uint32_t id) const717 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
718 {
719 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
720 for (const auto& rootNode : rootNodes) {
721 for (auto& node : rootNode->children_) {
722 if (node->GetWindowId() == id) {
723 return node;
724 }
725 for (auto& subNode : node->children_) {
726 if (subNode->GetWindowId() == id) {
727 return subNode;
728 }
729 }
730 }
731 }
732 return nullptr;
733 }
734
UpdateFocusStatus(uint32_t id,bool focused)735 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
736 {
737 auto node = FindWindowNodeById(id);
738 if (node == nullptr) {
739 WLOGFW("cannot find focused window id:%{public}d", id);
740 return;
741 }
742 if (focused) {
743 focusedPid_ = node->GetCallingPid();
744 }
745
746 if (node->GetCallingPid() == 0) {
747 WLOGFW("focused window is starting window, no need notify");
748 return;
749 }
750
751 if (focused && node->GetWindowProperty() != nullptr) {
752 AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
753 WLOGFW("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
754 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
755 node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
756 node->GetCallingPid(), node->GetCallingUid());
757 FocusAppInfo appInfo = { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_ };
758 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
759 }
760 if (node->GetWindowToken()) {
761 node->GetWindowToken()->UpdateFocusStatus(focused);
762 }
763 if (node->abilityToken_ == nullptr) {
764 WLOGFD("abilityToken is null, window : %{public}d", id);
765 }
766 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
767 node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
768 WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
769 focusChangeInfo, focused);
770 }
771
UpdateActiveStatus(uint32_t id,bool isActive)772 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
773 {
774 auto node = FindWindowNodeById(id);
775 if (node == nullptr) {
776 WLOGFE("cannot find active window id: %{public}d", id);
777 return;
778 }
779 if (isActive) {
780 activePid_ = node->GetCallingPid();
781 }
782 if (node->GetWindowToken()) {
783 node->GetWindowToken()->UpdateActiveStatus(isActive);
784 }
785 }
786
UpdateBrightness(uint32_t id,bool byRemoved)787 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
788 {
789 auto node = FindWindowNodeById(id);
790 if (node == nullptr) {
791 WLOGFE("cannot find active window id: %{public}d", id);
792 return;
793 }
794
795 if (!byRemoved) {
796 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
797 return;
798 }
799 }
800 WLOGFD("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
801 if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
802 if (GetDisplayBrightness() != node->GetBrightness()) {
803 WLOGFD("adjust brightness with default value");
804 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
805 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
806 }
807 SetBrightnessWindow(INVALID_WINDOW_ID);
808 } else {
809 if (GetDisplayBrightness() != node->GetBrightness()) {
810 WLOGFD("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
811 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
812 ToOverrideBrightness(node->GetBrightness()));
813 SetDisplayBrightness(node->GetBrightness());
814 }
815 SetBrightnessWindow(node->GetWindowId());
816 }
817 }
818
AssignZOrder()819 void WindowNodeContainer::AssignZOrder()
820 {
821 zOrder_ = 0;
822 WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
823 if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
824 ++zOrder_;
825 WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
826 return false;
827 }
828 if (node->leashWinSurfaceNode_ != nullptr) {
829 ++zOrder_;
830 node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
831 }
832
833 if (node->surfaceNode_ != nullptr) {
834 ++zOrder_;
835 node->surfaceNode_->SetPositionZ(zOrder_);
836 node->zOrder_ = zOrder_;
837 }
838 // make sure starting window above app
839 if (node->startingWinSurfaceNode_ != nullptr) {
840 ++zOrder_;
841 node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
842 }
843 return false;
844 };
845 TraverseWindowTree(func, false);
846 displayGroupController_->UpdateDisplayGroupWindowTree();
847 }
848
SetFocusWindow(uint32_t windowId)849 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
850 {
851 if (focusedWindow_ == windowId) {
852 WLOGFD("focused window no change, id: %{public}u, %{public}d", windowId, focusedPid_);
853 // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
854 // This info is invalid, so we must notify again when first frame callback.
855 if (focusedPid_ == 0) {
856 UpdateFocusStatus(windowId, true);
857 }
858 return WMError::WM_DO_NOTHING;
859 }
860 UpdateFocusStatus(focusedWindow_, false);
861 focusedWindow_ = windowId;
862 UpdateFocusStatus(focusedWindow_, true);
863 return WMError::WM_OK;
864 }
865
GetFocusWindow() const866 uint32_t WindowNodeContainer::GetFocusWindow() const
867 {
868 return focusedWindow_;
869 }
870
SetActiveWindow(uint32_t windowId,bool byRemoved)871 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
872 {
873 if (activeWindow_ == windowId) {
874 WLOGFD("active window not change, id: %{public}u, %{public}d", windowId, activePid_);
875 if (activePid_ == 0) {
876 UpdateActiveStatus(windowId, true);
877 }
878 return WMError::WM_DO_NOTHING;
879 }
880 UpdateActiveStatus(activeWindow_, false);
881 activeWindow_ = windowId;
882 UpdateActiveStatus(activeWindow_, true);
883 UpdateBrightness(activeWindow_, byRemoved);
884 return WMError::WM_OK;
885 }
886
SetDisplayBrightness(float brightness)887 void WindowNodeContainer::SetDisplayBrightness(float brightness)
888 {
889 displayBrightness_ = brightness;
890 }
891
GetDisplayBrightness() const892 float WindowNodeContainer::GetDisplayBrightness() const
893 {
894 return displayBrightness_;
895 }
896
SetBrightnessWindow(uint32_t windowId)897 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
898 {
899 brightnessWindow_ = windowId;
900 }
901
GetBrightnessWindow() const902 uint32_t WindowNodeContainer::GetBrightnessWindow() const
903 {
904 return brightnessWindow_;
905 }
906
ToOverrideBrightness(float brightness)907 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
908 {
909 return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
910 }
911
GetActiveWindow() const912 uint32_t WindowNodeContainer::GetActiveWindow() const
913 {
914 return activeWindow_;
915 }
916
GetLayoutPolicy() const917 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
918 {
919 return layoutPolicy_;
920 }
921
GetAvoidController() const922 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
923 {
924 return avoidController_;
925 }
926
GetMultiDisplayController() const927 sptr<DisplayGroupController> WindowNodeContainer::GetMultiDisplayController() const
928 {
929 return displayGroupController_;
930 }
931
GetRootNode(WindowRootNodeType type) const932 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
933 {
934 if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
935 return aboveAppWindowNode_;
936 } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
937 return appWindowNode_;
938 } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
939 return belowAppWindowNode_;
940 }
941 return nullptr;
942 }
943
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)944 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
945 {
946 if (requireLock && node->keepScreenLock_ == nullptr) {
947 // reset ipc identity
948 std::string identity = IPCSkeleton::ResetCallingIdentity();
949 node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
950 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
951 // set ipc identity to raw
952 IPCSkeleton::SetCallingIdentity(identity);
953 }
954 if (node->keepScreenLock_ == nullptr) {
955 return;
956 }
957 WLOGFD("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
958 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
959 node->GetWindowName().c_str(), requireLock);
960 ErrCode res;
961 // reset ipc identity
962 std::string identity = IPCSkeleton::ResetCallingIdentity();
963 if (requireLock) {
964 res = node->keepScreenLock_->Lock();
965 } else {
966 res = node->keepScreenLock_->UnLock();
967 }
968 // set ipc identity to raw
969 IPCSkeleton::SetCallingIdentity(identity);
970 if (res != ERR_OK) {
971 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
972 }
973 }
974
IsAboveSystemBarNode(sptr<WindowNode> node) const975 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
976 {
977 int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
978 if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
979 (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
980 return true;
981 }
982 return false;
983 }
984
IsSplitImmersiveNode(sptr<WindowNode> node) const985 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
986 {
987 auto type = node->GetWindowType();
988 return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
989 }
990
GetExpectImmersiveProperty() const991 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
992 {
993 std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
994 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty() },
995 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
996 };
997
998 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
999 for (const auto& node : rootNodes) {
1000 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
1001 auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1002 if (IsAboveSystemBarNode(*iter)) {
1003 continue;
1004 }
1005 if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1006 && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1007 WLOGFD("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1008 for (auto it : sysBarPropMap) {
1009 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1010 }
1011 return sysBarPropMap;
1012 } else if (IsSplitImmersiveNode(*iter)) {
1013 WLOGFD("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1014 for (auto it : sysBarPropMap) {
1015 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1016 sysBarPropMap[it.first].enable_ = false;
1017 }
1018 return sysBarPropMap;
1019 }
1020 }
1021 }
1022
1023 WLOGFD("No immersive window on top. Use default systembar Property");
1024 return sysBarPropMap;
1025 }
1026
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1027 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1028 const AvoidControlType avoidType) const
1029 {
1030 auto checkFunc = [this](sptr<WindowNode> node) {
1031 return CheckWindowNodeWhetherInWindowTree(node);
1032 };
1033 avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1034 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1035 NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1036 } else {
1037 NotifyIfSystemBarTintChanged(node->GetDisplayId());
1038 }
1039
1040 NotifyIfKeyboardRegionChanged(node, avoidType);
1041 }
1042
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1043 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1044 {
1045 avoidController_->SetFlagForProcessWindowChange(true);
1046 }
1047
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1048 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1049 {
1050 avoidController_->SetFlagForProcessWindowChange(false);
1051 auto checkFunc = [this](sptr<WindowNode> node) {
1052 return CheckWindowNodeWhetherInWindowTree(node);
1053 };
1054 WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1055 avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1056 return false;
1057 };
1058 TraverseWindowTree(func, true);
1059 }
1060
NotifyIfSystemBarTintChanged(DisplayId displayId) const1061 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1062 {
1063 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1064 auto expectSystemBarProp = GetExpectImmersiveProperty();
1065 SystemBarRegionTints tints;
1066 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1067 for (auto it : sysBarTintMap) {
1068 auto expectProp = expectSystemBarProp.find(it.first)->second;
1069 if (it.second.prop_ == expectProp) {
1070 continue;
1071 }
1072 WLOGFD("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1073 static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1074 sysBarTintMap[it.first].prop_ = expectProp;
1075 sysBarTintMap[it.first].type_ = it.first;
1076 tints.emplace_back(sysBarTintMap[it.first]);
1077 }
1078 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1079 }
1080
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1081 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1082 {
1083 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1084 SystemBarRegionTints tints;
1085 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1086 SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1087 for (auto it : sysBarTintMap) { // split screen mode not support yet
1088 auto sysNode = sysBarNodeMap[it.first];
1089 if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1090 continue;
1091 }
1092 const Rect& newRegion = sysNode->GetWindowRect();
1093 sysBarTintMap[it.first].region_ = newRegion;
1094 sysBarTintMap[it.first].type_ = it.first;
1095 tints.emplace_back(sysBarTintMap[it.first]);
1096 WLOGFD("system bar region update, type: %{public}d" \
1097 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1098 static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1099 }
1100 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1101 }
1102
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1103 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1104 const AvoidControlType avoidType) const
1105 {
1106 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1107 WLOGFD("windowType: %{public}u", node->GetWindowType());
1108 return;
1109 }
1110
1111 auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1112 if (callingWindow == nullptr) {
1113 WLOGFD("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1114 callingWindow = FindWindowNodeById(GetFocusWindow());
1115 }
1116 if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1117 WLOGFE("does not have correct callingWindow for input method window");
1118 return;
1119 }
1120 const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1121 if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1122 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1123 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1124 const Rect keyRect = node->GetWindowRect();
1125 const Rect callingRect = callingWindow->GetWindowRect();
1126 if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1127 WLOGFD("no overlap between two windows");
1128 return;
1129 }
1130 Rect overlapRect = { 0, 0, 0, 0 };
1131 if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1132 overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1133 }
1134
1135 WLOGFD("keyboard size change callingWindow: [%{public}s, %{public}u], " \
1136 "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1137 callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1138 overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1139 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT, overlapRect);
1140 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1141 return;
1142 }
1143 WLOGFE("does not have correct callingWindowMode for input method window");
1144 }
1145
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1146 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1147 {
1148 if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1149 WLOGE("[Immersive] the number of display is error");
1150 }
1151
1152 for (auto displayId : displayIdVec) {
1153 SystemBarRegionTints tints;
1154 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1155 for (auto it : sysBarTintMap) {
1156 WLOGFD("[Immersive] system bar cur notify, T: %{public}d, " \
1157 "V: %{public}d, C: %{public}x | %{public}x, " \
1158 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1159 static_cast<int32_t>(it.first),
1160 sysBarTintMap[it.first].prop_.enable_,
1161 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1162 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1163 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1164 tints.push_back(sysBarTintMap[it.first]);
1165 }
1166 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1167 }
1168 }
1169
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1170 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1171 {
1172 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1173 WLOGFD("[Immersive] begin isEnable: %{public}d", isEnable);
1174 if (isEnable) {
1175 for (auto& windowNode : appWindowNode_->children_) {
1176 if (windowNode->GetWindowId() == node->GetWindowId()) {
1177 continue;
1178 }
1179 if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1180 return;
1181 }
1182 }
1183 }
1184 SystemBarProperty prop;
1185 prop.enable_ = isEnable;
1186 SystemBarRegionTint tint;
1187 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1188 tint.prop_ = prop;
1189 SystemBarRegionTints tints;
1190 tints.push_back(tint);
1191 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1192 }
1193
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1194 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1195 {
1196 avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1197 }
1198
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1199 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1200 {
1201 if (rootNode->children_.empty()) {
1202 WLOGFE("root does not have any node");
1203 return false;
1204 }
1205 auto node = *(rootNode->children_.rbegin());
1206 if (node == nullptr) {
1207 WLOGFE("window tree does not have any node");
1208 return false;
1209 }
1210
1211 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1212 if ((*iter)->priority_ > 0) {
1213 return (*iter)->GetWindowId() == windowId;
1214 } else {
1215 break;
1216 }
1217 }
1218 return node->GetWindowId() == windowId;
1219 }
1220
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1221 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1222 std::vector<sptr<WindowNode>>& windowNodes)
1223 {
1224 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1225 uint32_t wid = (*iter)->GetWindowId();
1226 auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1227 [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1228 if (orderedIter != orderedNodes.end()) {
1229 iter = windowNodes.erase(iter);
1230 } else {
1231 iter++;
1232 }
1233 }
1234 for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1235 UpdateWindowTree(*iter);
1236 }
1237 return;
1238 }
1239
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1240 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1241 {
1242 if (windowNodes.empty()) {
1243 WLOGFE("windowNodes is empty!");
1244 return;
1245 }
1246 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1247 [windowId](sptr<WindowNode> node) {
1248 return node->GetWindowId() == windowId;
1249 });
1250 // raise app node window to top
1251 if (iter != windowNodes.end()) {
1252 sptr<WindowNode> node = *iter;
1253 windowNodes.erase(iter);
1254 UpdateWindowTree(node);
1255 WLOGFD("raise window to top %{public}u", node->GetWindowId());
1256 }
1257 }
1258
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1259 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1260 {
1261 for (auto& node : belowAppWindowNode_->children_) {
1262 TraverseWindowNode(node, windowNodes);
1263 }
1264 for (auto& node : appWindowNode_->children_) {
1265 TraverseWindowNode(node, windowNodes);
1266 }
1267 for (auto& node : aboveAppWindowNode_->children_) {
1268 TraverseWindowNode(node, windowNodes);
1269 }
1270 std::reverse(windowNodes.begin(), windowNodes.end());
1271 }
1272
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1273 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1274 {
1275 if (node == nullptr) {
1276 return;
1277 }
1278 auto iter = node->children_.begin();
1279 for (; iter < node->children_.end(); ++iter) {
1280 if ((*iter)->priority_ < 0) {
1281 windowNodes.emplace_back(*iter);
1282 } else {
1283 break;
1284 }
1285 }
1286 windowNodes.emplace_back(node);
1287 for (; iter < node->children_.end(); ++iter) {
1288 windowNodes.emplace_back(*iter);
1289 }
1290 }
1291
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType) const1292 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1293 {
1294 if (CheckWindowNodeWhetherInWindowTree(node)) {
1295 return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1296 }
1297 return {};
1298 }
1299
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1300 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1301 {
1302 bool isInWindowTree = false;
1303 WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1304 if (node->GetWindowId() == windowNode->GetWindowId()) {
1305 isInWindowTree = true;
1306 return true;
1307 }
1308 return false;
1309 };
1310 TraverseWindowTree(func, true);
1311 return isInWindowTree;
1312 }
1313
DumpScreenWindowTree()1314 void WindowNodeContainer::DumpScreenWindowTree()
1315 {
1316 WLOGFD("-------- dump window info begin---------");
1317 WLOGFD("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation abilityToken [ x y w h]");
1318 uint32_t zOrder = zOrder_;
1319 WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1320 Rect rect = node->GetWindowRect();
1321 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1322 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1323 WLOGFD("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1324 "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1325 windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1326 node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1327 node->abilityToken_ != nullptr, rect.posX_, rect.posY_, rect.width_, rect.height_);
1328 return false;
1329 };
1330 TraverseWindowTree(func, true);
1331 WLOGFD("-------- dump window info end ---------");
1332 }
1333
GetDisplayRect(DisplayId displayId) const1334 Rect WindowNodeContainer::GetDisplayRect(DisplayId displayId) const
1335 {
1336 return displayGroupInfo_->GetDisplayRect(displayId);
1337 }
1338
IsVerticalDisplay(DisplayId displayId) const1339 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1340 {
1341 return displayGroupInfo_->GetDisplayRect(displayId).width_ < displayGroupInfo_->GetDisplayRect(displayId).height_;
1342 }
1343
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1344 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1345 {
1346 switch (reason) {
1347 case WindowStateChangeReason::KEYGUARD: {
1348 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1349 TraverseAndUpdateWindowState(state, topPriority);
1350 break;
1351 }
1352 default:
1353 return;
1354 }
1355 }
1356
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1357 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1358 {
1359 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1360 for (auto& node : rootNodes) {
1361 UpdateWindowState(node, topPriority, state);
1362 }
1363 }
1364
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1365 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1366 {
1367 if (node == nullptr) {
1368 return;
1369 }
1370 if (node->parent_ != nullptr && node->currentVisibility_) {
1371 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1372 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1373 if (node->GetWindowToken()) {
1374 node->GetWindowToken()->UpdateWindowState(state);
1375 }
1376 HandleKeepScreenOn(node, state);
1377 }
1378 }
1379 for (auto& childNode : node->children_) {
1380 UpdateWindowState(childNode, topPriority, state);
1381 }
1382 }
1383
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1384 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1385 {
1386 if (node == nullptr) {
1387 WLOGFE("window is invalid");
1388 return;
1389 }
1390 if (state == WindowState::STATE_FROZEN) {
1391 HandleKeepScreenOn(node, false);
1392 } else if (state == WindowState::STATE_UNFROZEN) {
1393 HandleKeepScreenOn(node, node->IsKeepScreenOn());
1394 } else {
1395 // do nothing
1396 }
1397 }
1398
FindDividerNode() const1399 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1400 {
1401 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1402 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1403 return *iter;
1404 }
1405 }
1406 return nullptr;
1407 }
1408
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1409 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1410 {
1411 if (node == nullptr) {
1412 return;
1413 }
1414 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1415 if (windowPair == nullptr) {
1416 WLOGFE("Window pair is nullptr");
1417 return;
1418 }
1419 std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1420 RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1421 AssignZOrder();
1422 return;
1423 }
1424
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1425 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1426 {
1427 if (node == nullptr) {
1428 return WMError::WM_ERROR_NULLPTR;
1429 }
1430 if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1431 WLOGFD("it is already top app window, id: %{public}u", node->GetWindowId());
1432 return WMError::WM_ERROR_INVALID_TYPE;
1433 }
1434
1435 if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1436 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1437 if (parentNode == nullptr) {
1438 WLOGFE("window type is invalid");
1439 return WMError::WM_ERROR_NULLPTR;
1440 }
1441 RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1442 if (parentNode->IsSplitMode()) {
1443 RaiseSplitRelatedWindowToTop(parentNode);
1444 } else if (parentNode->parent_ != nullptr) {
1445 RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1446 }
1447 } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1448 if (node->IsSplitMode()) {
1449 RaiseSplitRelatedWindowToTop(node);
1450 } else {
1451 // remote animation continuous start and exit allow parent is nullptr
1452 if (node->parent_ == nullptr) {
1453 WLOGFW("node parent is nullptr");
1454 return WMError::WM_OK;
1455 }
1456 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1457 }
1458 } else {
1459 // do nothing
1460 }
1461 AssignZOrder();
1462 WLOGFD("RaiseZOrderForAppWindow finished");
1463 DumpScreenWindowTree();
1464 return WMError::WM_OK;
1465 }
1466
GetNextFocusableWindow(uint32_t windowId) const1467 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1468 {
1469 sptr<WindowNode> nextFocusableWindow;
1470 bool previousFocusedWindowFound = false;
1471 WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1472 sptr<WindowNode> node) {
1473 if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1474 nextFocusableWindow = node;
1475 return true;
1476 }
1477 if (node->GetWindowId() == windowId) {
1478 previousFocusedWindowFound = true;
1479 }
1480 return false;
1481 };
1482 TraverseWindowTree(func, true);
1483 return nextFocusableWindow;
1484 }
1485
GetNextRotatableWindow(uint32_t windowId) const1486 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1487 {
1488 sptr<WindowNode> nextRotatableWindow;
1489 WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1490 sptr<WindowNode> node) {
1491 if (windowId != node->GetWindowId() &&
1492 WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1493 nextRotatableWindow = node;
1494 return true;
1495 }
1496 return false;
1497 };
1498 TraverseWindowTree(func, true);
1499 return nextRotatableWindow;
1500 }
1501
GetNextActiveWindow(uint32_t windowId) const1502 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1503 {
1504 auto currentNode = FindWindowNodeById(windowId);
1505 if (currentNode == nullptr) {
1506 WLOGFE("cannot find window id: %{public}u by tree", windowId);
1507 return nullptr;
1508 }
1509 WLOGFD("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1510 if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1511 for (auto& node : appWindowNode_->children_) {
1512 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1513 continue;
1514 }
1515 return node;
1516 }
1517 for (auto& node : belowAppWindowNode_->children_) {
1518 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1519 return node;
1520 }
1521 }
1522 } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1523 std::vector<sptr<WindowNode>> windowNodes;
1524 TraverseContainer(windowNodes);
1525 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1526 return node->GetWindowId() == windowId;
1527 });
1528 if (iter == windowNodes.end()) {
1529 WLOGFE("could not find this window");
1530 return nullptr;
1531 }
1532 int index = std::distance(windowNodes.begin(), iter);
1533 for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1534 if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1535 || !windowNodes[i]->currentVisibility_) {
1536 continue;
1537 }
1538 return windowNodes[i];
1539 }
1540 } else {
1541 // do nothing
1542 }
1543 WLOGFE("could not get next active window");
1544 return nullptr;
1545 }
1546
IsForbidDockSliceMove(DisplayId displayId) const1547 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1548 {
1549 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1550 if (windowPair == nullptr) {
1551 WLOGFE("window pair is nullptr");
1552 return true;
1553 }
1554 if (windowPair->IsForbidDockSliceMove()) {
1555 return true;
1556 }
1557 return false;
1558 }
1559
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1560 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1561 {
1562 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1563 if (windowPair == nullptr) {
1564 WLOGFE("window pair is nullptr");
1565 return false;
1566 }
1567 std::vector<int32_t> exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId);
1568 if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1569 return false;
1570 }
1571 return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1572 }
1573
ExitSplitMode(DisplayId displayId)1574 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1575 {
1576 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1577 if (windowPair == nullptr) {
1578 WLOGFE("window pair is nullptr");
1579 return;
1580 }
1581 windowPair->ExitSplitMode();
1582 }
1583
MinimizeAllAppWindows(DisplayId displayId)1584 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1585 {
1586 WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1587 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1588 if (ret != WMError::WM_OK) {
1589 WLOGFE("Minimize all app window failed");
1590 }
1591 return;
1592 }
1593
GetDeskTopWindow()1594 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1595 {
1596 sptr<WindowNode> deskTop;
1597 WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1598 if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1599 deskTop = node;
1600 return true;
1601 }
1602 return false;
1603 };
1604 TraverseWindowTree(findDeskTopFunc, false);
1605 return deskTop;
1606 }
1607
HasPrivateWindow()1608 bool WindowNodeContainer::HasPrivateWindow()
1609 {
1610 std::vector<sptr<WindowNode>> windowNodes;
1611 TraverseContainer(windowNodes);
1612 for (const auto& node : windowNodes) {
1613 if (node->isVisible_ && node->GetWindowProperty()->GetPrivacyMode()) {
1614 WLOGFD("window name %{public}s", node->GetWindowName().c_str());
1615 return true;
1616 }
1617 }
1618 return false;
1619 }
1620
MinimizeOldestAppWindow()1621 void WindowNodeContainer::MinimizeOldestAppWindow()
1622 {
1623 for (auto& appNode : appWindowNode_->children_) {
1624 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1625 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1626 return;
1627 }
1628 }
1629 for (auto& appNode : aboveAppWindowNode_->children_) {
1630 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1631 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1632 return;
1633 }
1634 }
1635 WLOGFD("no window needs to minimize");
1636 }
1637
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)1638 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
1639 std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
1640 {
1641 WLOGFD("ToggleShownStateForAllAppWindows");
1642 for (auto node : aboveAppWindowNode_->children_) {
1643 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
1644 node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
1645 return WMError::WM_DO_NOTHING;
1646 }
1647 }
1648 // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
1649 if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
1650 backupWindowIds_.clear();
1651 backupWindowMode_.clear();
1652 backupDisplaySplitWindowMode_.clear();
1653 backupDividerWindowRect_.clear();
1654 }
1655 if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
1656 WLOGFD("backup");
1657 BackUpAllAppWindows();
1658 } else if (restore && !backupWindowIds_.empty()) {
1659 WLOGFD("restore");
1660 RestoreAllAppWindows(restoreFunc);
1661 } else {
1662 WLOGFD("do nothing because shown app windows is empty or backup windows is empty.");
1663 }
1664 return WMError::WM_OK;
1665 }
1666
BackUpAllAppWindows()1667 void WindowNodeContainer::BackUpAllAppWindows()
1668 {
1669 std::set<DisplayId> displayIdSet;
1670 backupWindowMode_.clear();
1671 backupDisplaySplitWindowMode_.clear();
1672 std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
1673 for (auto& appNode : children) {
1674 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1675 continue;
1676 }
1677 auto windowMode = appNode->GetWindowMode();
1678 backupWindowMode_[appNode->GetWindowId()] = windowMode;
1679 if (WindowHelper::IsSplitWindowMode(windowMode)) {
1680 backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
1681 }
1682 displayIdSet.insert(appNode->GetDisplayId());
1683 }
1684 for (auto& appNode : children) {
1685 // exclude exceptional window
1686 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1687 WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
1688 continue;
1689 }
1690 // minimize window
1691 WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
1692 backupWindowIds_.emplace_back(appNode->GetWindowId());
1693 WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId());
1694 wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
1695 WindowInnerManager::GetInstance().PostTask([abilityToken]() {
1696 auto token = abilityToken.promote();
1697 if (token == nullptr) {
1698 WLOGFW("Ability token is null");
1699 return;
1700 }
1701 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
1702 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
1703 });
1704 }
1705 backupDividerWindowRect_.clear();
1706 for (auto displayId : displayIdSet) {
1707 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1708 if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
1709 continue;
1710 }
1711 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
1712 }
1713 }
1714
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)1715 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
1716 {
1717 std::vector<uint32_t> backupWindowIds(backupWindowIds_);
1718 auto displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds();
1719 std::vector<sptr<WindowPair>> windowPairs;
1720 for (auto displayId : displayIds) {
1721 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1722 if (windowPair != nullptr) {
1723 if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
1724 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
1725 windowPair->SetAllSplitAppWindowsRestoring(true);
1726 }
1727 windowPairs.emplace_back(windowPair);
1728 }
1729 }
1730 for (auto windowId: backupWindowIds) {
1731 if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
1732 WLOGFE("restore %{public}u failed", windowId);
1733 continue;
1734 }
1735 WLOGFD("restore %{public}u", windowId);
1736 }
1737 for (auto windowPair : windowPairs) {
1738 windowPair->SetAllSplitAppWindowsRestoring(false);
1739 }
1740 layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
1741 backupWindowIds_.clear();
1742 backupWindowMode_.clear();
1743 backupDividerWindowRect_.clear();
1744 }
1745
IsAppWindowsEmpty() const1746 bool WindowNodeContainer::IsAppWindowsEmpty() const
1747 {
1748 return appWindowNode_->children_.empty();
1749 }
1750
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1751 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
1752 const std::vector<uint32_t> &exceptionalIds, const std::vector<WindowMode> &exceptionalModes)
1753 {
1754 if (appWindowNode_->children_.empty()) {
1755 return WMError::WM_OK;
1756 }
1757 for (auto& appNode : appWindowNode_->children_) {
1758 // exclude exceptional window
1759 if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1760 std::find(exceptionalModes.begin(), exceptionalModes.end(),
1761 appNode->GetWindowMode()) != exceptionalModes.end() ||
1762 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1763 continue;
1764 }
1765 MinimizeApp::AddNeedMinimizeApp(appNode, reason);
1766 }
1767 return WMError::WM_OK;
1768 }
1769
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)1770 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
1771 {
1772 std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
1773 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1774 return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
1775 }
1776
ResetLayoutPolicy()1777 void WindowNodeContainer::ResetLayoutPolicy()
1778 {
1779 layoutPolicy_->Reset();
1780 }
1781
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)1782 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
1783 {
1784 WLOGFD("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
1785 static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
1786 if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1787 WLOGFE("invalid layout mode");
1788 return WMError::WM_ERROR_INVALID_PARAM;
1789 }
1790 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1791 if (windowPair == nullptr) {
1792 WLOGFE("Window pair is nullptr");
1793 return WMError::WM_ERROR_NULLPTR;
1794 }
1795 if (layoutMode_ != dstMode) {
1796 if (layoutMode_ == WindowLayoutMode::CASCADE) {
1797 layoutPolicy_->Reset();
1798 windowPair->Clear();
1799 }
1800 layoutMode_ = dstMode;
1801 layoutPolicy_->Clean();
1802 layoutPolicy_ = layoutPolicies_[dstMode];
1803 layoutPolicy_->Launch();
1804 DumpScreenWindowTree();
1805 } else {
1806 WLOGFD("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1807 }
1808 if (reorder) {
1809 windowPair->Clear();
1810 layoutPolicy_->Reorder();
1811 DumpScreenWindowTree();
1812 }
1813 NotifyIfSystemBarTintChanged(displayId);
1814 return WMError::WM_OK;
1815 }
1816
UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode> & node,bool up)1817 void WindowNodeContainer::UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
1818 {
1819 if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestModeSupportInfo(),
1820 WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1821 WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
1822 return;
1823 }
1824 uint32_t modeSupportInfo;
1825 if (up) {
1826 modeSupportInfo = node->GetModeSupportInfo() & (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1827 } else {
1828 modeSupportInfo = node->GetModeSupportInfo() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
1829 }
1830 node->SetModeSupportInfo(modeSupportInfo);
1831 if (node->GetWindowToken() != nullptr) {
1832 node->GetWindowToken()->UpdateWindowModeSupportInfo(modeSupportInfo);
1833 }
1834 }
1835
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1836 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1837 {
1838 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || !isScreenLocked_) {
1839 return;
1840 }
1841
1842 WLOGFD("raise input method float window priority.");
1843 node->priority_ = zorderPolicy_->GetWindowPriority(
1844 WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1845 }
1846
ReZOrderShowWhenLockedWindows(bool up)1847 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
1848 {
1849 WLOGFD("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1850 std::vector<sptr<WindowNode>> needReZOrderNodes;
1851 auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1852 auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1853
1854 auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1855 zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1856
1857 for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1858 if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1859 needReZOrderNodes.emplace_back(*iter);
1860 iter = srcRoot->children_.erase(iter);
1861 } else {
1862 iter++;
1863 }
1864 }
1865
1866 for (auto& needReZOrderNode : needReZOrderNodes) {
1867 needReZOrderNode->priority_ = dstPriority;
1868 needReZOrderNode->parent_ = dstRoot;
1869 auto parentNode = needReZOrderNode->parent_;
1870 auto position = parentNode->children_.end();
1871 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1872 if ((*iter)->priority_ > needReZOrderNode->priority_) {
1873 position = iter;
1874 break;
1875 }
1876 }
1877
1878 UpdateModeSupportInfoWhenKeyguardChange(needReZOrderNode, up);
1879
1880 parentNode->children_.insert(position, needReZOrderNode);
1881 if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
1882 needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
1883 if (needReZOrderNode->GetWindowToken() != nullptr) {
1884 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
1885 }
1886 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
1887 if (windowPair == nullptr) {
1888 WLOGFE("Window pair is nullptr");
1889 return;
1890 }
1891 windowPair->UpdateIfSplitRelated(needReZOrderNode);
1892 }
1893 WLOGFD("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
1894 }
1895 }
1896
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1897 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1898 {
1899 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1900 !isScreenLocked_) {
1901 return;
1902 }
1903
1904 WLOGFD("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
1905 ReZOrderShowWhenLockedWindows(true);
1906 }
1907
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1908 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1909 {
1910 // if keyguard window show, raise show when locked windows
1911 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1912 ReZOrderShowWhenLockedWindows(true);
1913 return;
1914 }
1915
1916 // if show when locked window show, raise itself when exist keyguard
1917 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1918 !isScreenLocked_) {
1919 return;
1920 }
1921
1922 WLOGFD("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1923 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1924 node->parent_ = aboveAppWindowNode_;
1925 if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
1926 node->GetWindowProperty()->ResumeLastWindowMode();
1927 if (node->GetWindowToken() != nullptr) {
1928 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1929 }
1930 }
1931 }
1932
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1933 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1934 {
1935 // if keyguard window hide, drop show when locked windows
1936 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1937 ReZOrderShowWhenLockedWindows(false);
1938 AssignZOrder();
1939 }
1940 }
1941
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1942 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1943 {
1944 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1945 if (isFromTopToBottom) {
1946 std::reverse(rootNodes.begin(), rootNodes.end());
1947 }
1948
1949 for (const auto& node : rootNodes) {
1950 if (isFromTopToBottom) {
1951 for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1952 if (TraverseFromTopToBottom(*iter, func)) {
1953 return;
1954 }
1955 }
1956 } else {
1957 for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1958 if (TraverseFromBottomToTop(*iter, func)) {
1959 return;
1960 }
1961 }
1962 }
1963 }
1964 }
1965
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1966 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1967 {
1968 if (node == nullptr) {
1969 return false;
1970 }
1971 auto iterBegin = node->children_.rbegin();
1972 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1973 if ((*iterBegin)->priority_ <= 0) {
1974 break;
1975 }
1976 if (func(*iterBegin)) {
1977 return true;
1978 }
1979 }
1980 if (func(node)) {
1981 return true;
1982 }
1983 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1984 if (func(*iterBegin)) {
1985 return true;
1986 }
1987 }
1988 return false;
1989 }
1990
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1991 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1992 {
1993 if (node == nullptr) {
1994 return false;
1995 }
1996 auto iterBegin = node->children_.begin();
1997 for (; iterBegin != node->children_.end(); ++iterBegin) {
1998 if ((*iterBegin)->priority_ >= 0) {
1999 break;
2000 }
2001 if (func(*iterBegin)) {
2002 return true;
2003 }
2004 }
2005 if (func(node)) {
2006 return true;
2007 }
2008 for (; iterBegin != node->children_.end(); ++iterBegin) {
2009 if (func(*iterBegin)) {
2010 return true;
2011 }
2012 }
2013 return false;
2014 }
2015
GetVirtualPixelRatio(DisplayId displayId) const2016 float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const
2017 {
2018 return layoutPolicy_->GetVirtualPixelRatio(displayId);
2019 }
2020
GetDisplayGroupRect() const2021 Rect WindowNodeContainer::GetDisplayGroupRect() const
2022 {
2023 return layoutPolicy_->GetDisplayGroupRect();
2024 }
2025
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2026 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2027 {
2028 if (node == nullptr) {
2029 WLOGFE("could not find window");
2030 return WMError::WM_ERROR_NULLPTR;
2031 }
2032 WindowMode srcMode = node->GetWindowMode();
2033 if (srcMode == dstMode) {
2034 return WMError::WM_OK;
2035 }
2036
2037 if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2038 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2039 return WMError::WM_ERROR_INVALID_PARAM;
2040 }
2041
2042 WMError res = WMError::WM_OK;
2043 if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2044 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2045 } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2046 node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2047 if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2048 node->SetRequestRect(node->GetWindowRect());
2049 }
2050 } else {
2051 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2052 }
2053 node->SetWindowMode(dstMode);
2054 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2055 if (windowPair == nullptr) {
2056 WLOGFE("Window pair is nullptr");
2057 return WMError::WM_ERROR_NULLPTR;
2058 }
2059 windowPair->UpdateIfSplitRelated(node);
2060 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2061 if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2062 NotifyDockWindowStateChanged(node, true);
2063 } else {
2064 NotifyDockWindowStateChanged(node, false);
2065 }
2066 }
2067
2068 if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2069 WindowHelper::IsAppWindow(node->GetWindowType())) {
2070 // minimize other app window
2071 res = MinimizeStructuredAppWindowsExceptSelf(node);
2072 if (res != WMError::WM_OK) {
2073 return res;
2074 }
2075 }
2076 if (node->GetWindowToken() != nullptr) {
2077 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2078 }
2079 res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2080 if (res != WMError::WM_OK) {
2081 WLOGFE("Set window mode failed, update node failed");
2082 return res;
2083 }
2084 return WMError::WM_OK;
2085 }
2086
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2087 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2088 const ModeChangeHotZonesConfig& config)
2089 {
2090 const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId);
2091
2092 hotZones.fullscreen_.width_ = displayRect.width_;
2093 hotZones.fullscreen_.height_ = config.fullscreenRange_;
2094
2095 hotZones.primary_.width_ = config.primaryRange_;
2096 hotZones.primary_.height_ = displayRect.height_;
2097
2098 hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2099 hotZones.secondary_.width_ = config.secondaryRange_;
2100 hotZones.secondary_.height_ = displayRect.height_;
2101 }
2102
GetDisplayVirtualPixelRatio(DisplayId displayId) const2103 float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) const
2104 {
2105 return displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId);
2106 }
2107
GetDisplayInfo(DisplayId displayId)2108 sptr<DisplayInfo> WindowNodeContainer::GetDisplayInfo(DisplayId displayId)
2109 {
2110 return displayGroupInfo_->GetDisplayInfo(displayId);
2111 }
2112
UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)2113 void WindowNodeContainer::UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)
2114 {
2115 displayGroupInfo_->UpdateDisplayInfo(displayInfo);
2116 }
2117
GetAllDisplayInfo()2118 std::vector<sptr<DisplayInfo>> WindowNodeContainer::GetAllDisplayInfo()
2119 {
2120 return displayGroupInfo_->GetAllDisplayInfo();
2121 }
2122
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2123 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2124 {
2125 if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2126 WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2127 }
2128 }
2129
GetCurrentLayoutMode() const2130 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2131 {
2132 return layoutMode_;
2133 }
2134
RemoveSingleUserWindowNodes(int accountId)2135 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2136 {
2137 std::vector<sptr<WindowNode>> windowNodes;
2138 TraverseContainer(windowNodes);
2139 WLOGFD("%{public}d", accountId);
2140 for (auto& windowNode : windowNodes) {
2141 int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2142 if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2143 WLOGFD("skiped window %{public}s, windowId %{public}d uid %{public}d",
2144 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2145 continue;
2146 }
2147 WLOGFD("remove window %{public}s, windowId %{public}d uid %{public}d",
2148 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2149 windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2150 if (windowNode->GetWindowToken()) {
2151 if (windowNode->surfaceNode_ != nullptr) {
2152 windowNode->surfaceNode_->SetVisible(true);
2153 }
2154 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2155 }
2156 }
2157 }
2158
TakeWindowPairSnapshot(DisplayId displayId)2159 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2160 {
2161 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2162 return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2163 }
2164
ClearWindowPairSnapshot(DisplayId displayId)2165 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2166 {
2167 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2168 if (windowPair == nullptr) {
2169 WLOGFE("Window pair is nullptr");
2170 return;
2171 }
2172 windowPair->ClearPairSnapshot();
2173 }
2174
IsScreenLocked()2175 bool WindowNodeContainer::IsScreenLocked()
2176 {
2177 return isScreenLocked_;
2178 }
2179 } // namespace Rosen
2180 } // namespace OHOS
2181