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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("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 WLOGFI("DestroyWindowNode windowId: %{public}u end", node->GetWindowId());
455 return WMError::WM_OK;
456 }
457
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)458 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
459 {
460 if (!node->GetWindowToken()) {
461 WLOGFE("windowToken is null");
462 return;
463 }
464 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
465 for (auto& childNode : appWindowNode_->children_) {
466 if (childNode->IsSplitMode()) {
467 layoutPolicy_->UpdateClientRect(childNode->GetWindowRect(), childNode, reason);
468 childNode->ResetWindowSizeChangeReason();
469 WLOGFI("Notify split window that the drag action is start or end, windowId: %{public}d, "
470 "reason: %{public}u", childNode->GetWindowId(), reason);
471 }
472 }
473 } else {
474 layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, reason);
475 node->ResetWindowSizeChangeReason();
476 WLOGFI("Notify window that the drag action is start or end, windowId: %{public}d, "
477 "reason: %{public}u", node->GetWindowId(), reason);
478 }
479 }
480
UpdateWindowTree(sptr<WindowNode> & node)481 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
482 {
483 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
484 node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
485 RaiseInputMethodWindowPriorityIfNeeded(node);
486 RaiseShowWhenLockedWindowIfNeeded(node);
487 auto parentNode = node->parent_;
488 if (parentNode == nullptr) {
489 WLOGFI("Current window node has no parent: %{public}u", node->GetWindowId());
490 return;
491 }
492 auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
493 if (iter != parentNode->children_.end()) {
494 WLOGFI("node %{public}u is already on window tree, no need to update!", node->GetWindowId());
495 return;
496 }
497 auto position = parentNode->children_.end();
498 int splitWindowCnt = 0;
499 for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
500 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
501 position = child;
502 break;
503 }
504 if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
505 splitWindowCnt++;
506 }
507 if ((*child)->priority_ > node->priority_) {
508 position = child;
509 break;
510 }
511 }
512 parentNode->children_.insert(position, node);
513 }
514
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)515 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
516 {
517 /*
518 * App main window must has starting window, and show after starting window
519 * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
520 * Just need add appSurface Node as child of leashWindowSurfaceNode
521 */
522 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree");
523 if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
524 WLOGFE("id:%{public}u not main app window but has start window", node->GetWindowId());
525 return false;
526 }
527 if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
528 WLOGFE("id:%{public}u leashWinSurfaceNode or surfaceNode is null but has start window!", node->GetWindowId());
529 return false;
530 }
531 WLOGFI("AddAppSurfaceNodeOnRSTree windowId: %{public}d", node->GetWindowId());
532 if (!node->currentVisibility_) {
533 WLOGFI("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
534 return false;
535 }
536 node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
537 return true;
538 }
539
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)540 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
541 WindowUpdateType type, bool animationPlayed)
542 {
543 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
544 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
545 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
546 WLOGFI("not need to update RSTree");
547 return true;
548 }
549 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
550 WLOGFI("AddNodeOnRSTree windowId: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
551 "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
552 node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
553 auto updateRSTreeFunc = [&]() {
554 auto& dms = DisplayManagerServiceInner::GetInstance();
555 if (!node->currentVisibility_) {
556 WLOGFI("window: %{public}d is invisible, do not need update RS tree", node->GetWindowId());
557 return;
558 }
559 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
560 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
561 for (auto& child : node->children_) {
562 if (child->currentVisibility_) {
563 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
564 }
565 }
566 };
567
568 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
569 updateRSTreeFunc();
570 return true;
571 }
572
573 if (node->EnableDefaultAnimation(animationPlayed)) {
574 WLOGFI("add window with animation");
575 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
576 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
577 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
578 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
579 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
580 !animationPlayed) { // add keyboard with animation
581 ProcessInputMethodWindowAddAnimation(node, updateRSTreeFunc);
582 } else {
583 WLOGFI("add window without animation");
584 updateRSTreeFunc();
585 }
586 return true;
587 }
588
ProcessInputMethodWindowAddAnimation(sptr<WindowNode> & node,std::function<void ()> updateRSTreeFunc)589 void WindowNodeContainer::ProcessInputMethodWindowAddAnimation(sptr<WindowNode>& node,
590 std::function<void()> updateRSTreeFunc)
591 {
592 static sptr<WindowNode> imeNode = nullptr;
593 if (imeNode == node && imeNode != nullptr && imeNode->surfaceNode_ != nullptr) {
594 WLOGFI("imeNode SetAppFreeze(true)");
595 imeNode->surfaceNode_->SetAppFreeze(true);
596 }
597 sptr<WindowNode> launcherNode = nullptr;
598 for (auto& windowNode : belowAppWindowNode_->children_) {
599 if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
600 launcherNode = windowNode;
601 break;
602 }
603 }
604 if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
605 WLOGFI("launcherNode SetAppFreeze(true)");
606 launcherNode->surfaceNode_->SetAppFreeze(true);
607 }
608 auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationIn_;
609 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc,
610 [ime = imeNode, node, launcherNode]() {
611 if (ime == node && ime != nullptr && ime->surfaceNode_ != nullptr) {
612 WLOGFI("imeNode SetAppFreeze(false)");
613 ime->surfaceNode_->SetAppFreeze(false);
614 }
615 if (launcherNode != nullptr && launcherNode->surfaceNode_ != nullptr) {
616 WLOGFI("launcherNode SetAppFreeze(false)");
617 launcherNode->surfaceNode_->SetAppFreeze(false);
618 }
619 auto transactionProxy = RSTransactionProxy::GetInstance();
620 if (transactionProxy != nullptr) {
621 transactionProxy->FlushImplicitTransaction();
622 }
623 });
624 imeNode = node;
625 }
626
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)627 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
628 WindowUpdateType type, bool animationPlayed)
629 {
630 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
631 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
632 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
633 WLOGFI("not need to update RSTree");
634 return true;
635 }
636 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
637 WLOGFI("RemoveNodeFromRSTree windowId: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
638 "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
639 node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
640 auto updateRSTreeFunc = [&]() {
641 auto& dms = DisplayManagerServiceInner::GetInstance();
642 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
643 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
644 for (auto& child : node->children_) {
645 if (child->currentVisibility_) {
646 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
647 }
648 }
649 };
650
651 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
652 updateRSTreeFunc();
653 return true;
654 }
655
656 if (node->EnableDefaultAnimation(animationPlayed)) {
657 WLOGFI("remove window with animation");
658 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
659 if (node->surfaceNode_) {
660 node->surfaceNode_->SetAppFreeze(true);
661 }
662 wptr<WindowNode> weakNode(node);
663 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
664 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
665 auto weakWindow = weakNode.promote();
666 if (weakWindow && weakWindow->surfaceNode_) {
667 weakWindow->surfaceNode_->SetAppFreeze(false);
668 }
669 });
670 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
671 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
672 !animationPlayed) { // remove keyboard with animation
673 auto timingProtocol = animationConfig_.keyboardAnimationConfig_.durationOut_;
674 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc);
675 } else {
676 WLOGFI("remove window without animation");
677 updateRSTreeFunc();
678 }
679 return true;
680 }
681
Destroy()682 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
683 {
684 // clear vector cache completely, swap with empty vector
685 auto emptyVector = std::vector<uint32_t>();
686 removedIds_.swap(emptyVector);
687 for (auto& node : belowAppWindowNode_->children_) {
688 DestroyWindowNode(node, removedIds_);
689 }
690 for (auto& node : appWindowNode_->children_) {
691 DestroyWindowNode(node, removedIds_);
692 }
693 for (auto& node : aboveAppWindowNode_->children_) {
694 DestroyWindowNode(node, removedIds_);
695 }
696 return removedIds_;
697 }
698
FindRoot(WindowType type) const699 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
700 {
701 if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
702 type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
703 type == WindowType::WINDOW_TYPE_DIALOG) {
704 return appWindowNode_;
705 }
706 if (WindowHelper::IsBelowSystemWindow(type)) {
707 return belowAppWindowNode_;
708 }
709 if (WindowHelper::IsAboveSystemWindow(type)) {
710 return aboveAppWindowNode_;
711 }
712 return nullptr;
713 }
714
FindWindowNodeById(uint32_t id) const715 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
716 {
717 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
718 for (const auto& rootNode : rootNodes) {
719 for (auto& node : rootNode->children_) {
720 if (node->GetWindowId() == id) {
721 return node;
722 }
723 for (auto& subNode : node->children_) {
724 if (subNode->GetWindowId() == id) {
725 return subNode;
726 }
727 }
728 }
729 }
730 return nullptr;
731 }
732
UpdateFocusStatus(uint32_t id,bool focused)733 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
734 {
735 auto node = FindWindowNodeById(id);
736 if (node == nullptr) {
737 WLOGFW("cannot find focused window id:%{public}d", id);
738 return;
739 }
740 if (focused) {
741 focusedPid_ = node->GetCallingPid();
742 }
743
744 if (node->GetCallingPid() == 0) {
745 WLOGFW("focused window is starting window, no need notify");
746 return;
747 }
748
749 if (focused && node->GetWindowProperty() != nullptr) {
750 AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
751 WLOGFW("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
752 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
753 node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
754 node->GetCallingPid(), node->GetCallingUid());
755 FocusAppInfo appInfo = { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_ };
756 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
757 }
758 if (node->GetWindowToken()) {
759 node->GetWindowToken()->UpdateFocusStatus(focused);
760 }
761 if (node->abilityToken_ == nullptr) {
762 WLOGFI("abilityToken is null, window : %{public}d", id);
763 }
764 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
765 node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
766 WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
767 focusChangeInfo, focused);
768 }
769
UpdateActiveStatus(uint32_t id,bool isActive)770 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
771 {
772 auto node = FindWindowNodeById(id);
773 if (node == nullptr) {
774 WLOGFE("cannot find active window id: %{public}d", id);
775 return;
776 }
777 if (isActive) {
778 activePid_ = node->GetCallingPid();
779 }
780 if (node->GetWindowToken()) {
781 node->GetWindowToken()->UpdateActiveStatus(isActive);
782 }
783 }
784
UpdateBrightness(uint32_t id,bool byRemoved)785 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
786 {
787 auto node = FindWindowNodeById(id);
788 if (node == nullptr) {
789 WLOGFE("cannot find active window id: %{public}d", id);
790 return;
791 }
792
793 if (!byRemoved) {
794 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
795 return;
796 }
797 }
798 WLOGFI("brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
799 if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
800 if (GetDisplayBrightness() != node->GetBrightness()) {
801 WLOGFI("adjust brightness with default value");
802 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
803 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
804 }
805 SetBrightnessWindow(INVALID_WINDOW_ID);
806 } else {
807 if (GetDisplayBrightness() != node->GetBrightness()) {
808 WLOGFI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
809 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
810 ToOverrideBrightness(node->GetBrightness()));
811 SetDisplayBrightness(node->GetBrightness());
812 }
813 SetBrightnessWindow(node->GetWindowId());
814 }
815 }
816
AssignZOrder()817 void WindowNodeContainer::AssignZOrder()
818 {
819 zOrder_ = 0;
820 WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
821 if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
822 ++zOrder_;
823 WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
824 return false;
825 }
826 if (node->leashWinSurfaceNode_ != nullptr) {
827 ++zOrder_;
828 node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
829 }
830
831 if (node->surfaceNode_ != nullptr) {
832 ++zOrder_;
833 node->surfaceNode_->SetPositionZ(zOrder_);
834 node->zOrder_ = zOrder_;
835 }
836 // make sure starting window above app
837 if (node->startingWinSurfaceNode_ != nullptr) {
838 ++zOrder_;
839 node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
840 }
841 return false;
842 };
843 TraverseWindowTree(func, false);
844 displayGroupController_->UpdateDisplayGroupWindowTree();
845 }
846
SetFocusWindow(uint32_t windowId)847 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
848 {
849 if (focusedWindow_ == windowId) {
850 WLOGFI("focused window no change, id: %{public}u, %{public}d", windowId, focusedPid_);
851 // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
852 // This info is invalid, so we must notify again when first frame callback.
853 if (focusedPid_ == 0) {
854 UpdateFocusStatus(windowId, true);
855 }
856 return WMError::WM_DO_NOTHING;
857 }
858 UpdateFocusStatus(focusedWindow_, false);
859 focusedWindow_ = windowId;
860 UpdateFocusStatus(focusedWindow_, true);
861 return WMError::WM_OK;
862 }
863
GetFocusWindow() const864 uint32_t WindowNodeContainer::GetFocusWindow() const
865 {
866 return focusedWindow_;
867 }
868
SetActiveWindow(uint32_t windowId,bool byRemoved)869 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
870 {
871 if (activeWindow_ == windowId) {
872 WLOGI("active window not change, id: %{public}u, %{public}d", windowId, activePid_);
873 if (activePid_ == 0) {
874 UpdateActiveStatus(windowId, true);
875 }
876 return WMError::WM_DO_NOTHING;
877 }
878 UpdateActiveStatus(activeWindow_, false);
879 activeWindow_ = windowId;
880 UpdateActiveStatus(activeWindow_, true);
881 UpdateBrightness(activeWindow_, byRemoved);
882 return WMError::WM_OK;
883 }
884
SetDisplayBrightness(float brightness)885 void WindowNodeContainer::SetDisplayBrightness(float brightness)
886 {
887 displayBrightness_ = brightness;
888 }
889
GetDisplayBrightness() const890 float WindowNodeContainer::GetDisplayBrightness() const
891 {
892 return displayBrightness_;
893 }
894
SetBrightnessWindow(uint32_t windowId)895 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
896 {
897 brightnessWindow_ = windowId;
898 }
899
GetBrightnessWindow() const900 uint32_t WindowNodeContainer::GetBrightnessWindow() const
901 {
902 return brightnessWindow_;
903 }
904
ToOverrideBrightness(float brightness)905 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
906 {
907 return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
908 }
909
GetActiveWindow() const910 uint32_t WindowNodeContainer::GetActiveWindow() const
911 {
912 return activeWindow_;
913 }
914
GetLayoutPolicy() const915 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
916 {
917 return layoutPolicy_;
918 }
919
GetAvoidController() const920 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
921 {
922 return avoidController_;
923 }
924
GetMultiDisplayController() const925 sptr<DisplayGroupController> WindowNodeContainer::GetMultiDisplayController() const
926 {
927 return displayGroupController_;
928 }
929
GetRootNode(WindowRootNodeType type) const930 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
931 {
932 if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
933 return aboveAppWindowNode_;
934 } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
935 return appWindowNode_;
936 } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
937 return belowAppWindowNode_;
938 }
939 return nullptr;
940 }
941
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)942 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
943 {
944 if (requireLock && node->keepScreenLock_ == nullptr) {
945 // reset ipc identity
946 std::string identity = IPCSkeleton::ResetCallingIdentity();
947 node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
948 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
949 // set ipc identity to raw
950 IPCSkeleton::SetCallingIdentity(identity);
951 }
952 if (node->keepScreenLock_ == nullptr) {
953 return;
954 }
955 WLOGFI("handle keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
956 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
957 node->GetWindowName().c_str(), requireLock);
958 ErrCode res;
959 // reset ipc identity
960 std::string identity = IPCSkeleton::ResetCallingIdentity();
961 if (requireLock) {
962 res = node->keepScreenLock_->Lock();
963 } else {
964 res = node->keepScreenLock_->UnLock();
965 }
966 // set ipc identity to raw
967 IPCSkeleton::SetCallingIdentity(identity);
968 if (res != ERR_OK) {
969 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
970 }
971 }
972
IsAboveSystemBarNode(sptr<WindowNode> node) const973 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
974 {
975 int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
976 if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
977 (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
978 return true;
979 }
980 return false;
981 }
982
IsSplitImmersiveNode(sptr<WindowNode> node) const983 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
984 {
985 auto type = node->GetWindowType();
986 return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
987 }
988
GetExpectImmersiveProperty() const989 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty() const
990 {
991 std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
992 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty() },
993 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
994 };
995
996 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
997 for (const auto& node : rootNodes) {
998 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
999 auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1000 if (IsAboveSystemBarNode(*iter)) {
1001 continue;
1002 }
1003 if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1004 && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1005 WLOGFI("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1006 for (auto it : sysBarPropMap) {
1007 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1008 }
1009 return sysBarPropMap;
1010 } else if (IsSplitImmersiveNode(*iter)) {
1011 WLOGFI("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1012 for (auto it : sysBarPropMap) {
1013 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1014 sysBarPropMap[it.first].enable_ = false;
1015 }
1016 return sysBarPropMap;
1017 }
1018 }
1019 }
1020
1021 WLOGFI("No immersive window on top. Use default systembar Property");
1022 return sysBarPropMap;
1023 }
1024
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1025 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1026 const AvoidControlType avoidType) const
1027 {
1028 auto checkFunc = [this](sptr<WindowNode> node) {
1029 return CheckWindowNodeWhetherInWindowTree(node);
1030 };
1031 avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1032 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1033 NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1034 } else {
1035 NotifyIfSystemBarTintChanged(node->GetDisplayId());
1036 }
1037
1038 NotifyIfKeyboardRegionChanged(node, avoidType);
1039 }
1040
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1041 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1042 {
1043 avoidController_->SetFlagForProcessWindowChange(true);
1044 }
1045
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1046 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1047 {
1048 avoidController_->SetFlagForProcessWindowChange(false);
1049 auto checkFunc = [this](sptr<WindowNode> node) {
1050 return CheckWindowNodeWhetherInWindowTree(node);
1051 };
1052 WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1053 avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1054 return false;
1055 };
1056 TraverseWindowTree(func, true);
1057 }
1058
NotifyIfSystemBarTintChanged(DisplayId displayId) const1059 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1060 {
1061 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1062 auto expectSystemBarProp = GetExpectImmersiveProperty();
1063 SystemBarRegionTints tints;
1064 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1065 for (auto it : sysBarTintMap) {
1066 auto expectProp = expectSystemBarProp.find(it.first)->second;
1067 if (it.second.prop_ == expectProp) {
1068 continue;
1069 }
1070 WLOGFI("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1071 static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1072 sysBarTintMap[it.first].prop_ = expectProp;
1073 sysBarTintMap[it.first].type_ = it.first;
1074 tints.emplace_back(sysBarTintMap[it.first]);
1075 }
1076 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1077 }
1078
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1079 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1080 {
1081 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1082 SystemBarRegionTints tints;
1083 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1084 SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1085 for (auto it : sysBarTintMap) { // split screen mode not support yet
1086 auto sysNode = sysBarNodeMap[it.first];
1087 if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1088 continue;
1089 }
1090 const Rect& newRegion = sysNode->GetWindowRect();
1091 sysBarTintMap[it.first].region_ = newRegion;
1092 sysBarTintMap[it.first].type_ = it.first;
1093 tints.emplace_back(sysBarTintMap[it.first]);
1094 WLOGFI("system bar region update, type: %{public}d" \
1095 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1096 static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1097 }
1098 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1099 }
1100
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1101 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1102 const AvoidControlType avoidType) const
1103 {
1104 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1105 WLOGFD("windowType: %{public}u", node->GetWindowType());
1106 return;
1107 }
1108
1109 auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1110 if (callingWindow == nullptr) {
1111 WLOGFI("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1112 callingWindow = FindWindowNodeById(GetFocusWindow());
1113 }
1114 if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1115 WLOGFE("does not have correct callingWindow for input method window");
1116 return;
1117 }
1118 const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1119 if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1120 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1121 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1122 const Rect keyRect = node->GetWindowRect();
1123 const Rect callingRect = callingWindow->GetWindowRect();
1124 if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1125 WLOGFD("no overlap between two windows");
1126 return;
1127 }
1128 Rect overlapRect = { 0, 0, 0, 0 };
1129 if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1130 overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1131 }
1132
1133 WLOGFI("keyboard size change callingWindow: [%{public}s, %{public}u], " \
1134 "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1135 callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1136 overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1137 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT, overlapRect);
1138 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1139 return;
1140 }
1141 WLOGFE("does not have correct callingWindowMode for input method window");
1142 }
1143
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1144 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1145 {
1146 if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1147 WLOGE("[Immersive] the number of display is error");
1148 }
1149
1150 for (auto displayId : displayIdVec) {
1151 SystemBarRegionTints tints;
1152 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1153 for (auto it : sysBarTintMap) {
1154 WLOGFI("[Immersive] system bar cur notify, T: %{public}d, " \
1155 "V: %{public}d, C: %{public}x | %{public}x, " \
1156 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1157 static_cast<int32_t>(it.first),
1158 sysBarTintMap[it.first].prop_.enable_,
1159 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1160 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1161 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1162 tints.push_back(sysBarTintMap[it.first]);
1163 }
1164 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1165 }
1166 }
1167
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1168 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1169 {
1170 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1171 WLOGFI("[Immersive] begin isEnable: %{public}d", isEnable);
1172 if (isEnable) {
1173 for (auto& windowNode : appWindowNode_->children_) {
1174 if (windowNode->GetWindowId() == node->GetWindowId()) {
1175 continue;
1176 }
1177 if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1178 return;
1179 }
1180 }
1181 }
1182 SystemBarProperty prop;
1183 prop.enable_ = isEnable;
1184 SystemBarRegionTint tint;
1185 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1186 tint.prop_ = prop;
1187 SystemBarRegionTints tints;
1188 tints.push_back(tint);
1189 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1190 }
1191
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1192 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1193 {
1194 avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1195 }
1196
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1197 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1198 {
1199 if (rootNode->children_.empty()) {
1200 WLOGFE("root does not have any node");
1201 return false;
1202 }
1203 auto node = *(rootNode->children_.rbegin());
1204 if (node == nullptr) {
1205 WLOGFE("window tree does not have any node");
1206 return false;
1207 }
1208
1209 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1210 if ((*iter)->priority_ > 0) {
1211 return (*iter)->GetWindowId() == windowId;
1212 } else {
1213 break;
1214 }
1215 }
1216 return node->GetWindowId() == windowId;
1217 }
1218
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1219 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1220 std::vector<sptr<WindowNode>>& windowNodes)
1221 {
1222 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1223 uint32_t wid = (*iter)->GetWindowId();
1224 auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1225 [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1226 if (orderedIter != orderedNodes.end()) {
1227 iter = windowNodes.erase(iter);
1228 } else {
1229 iter++;
1230 }
1231 }
1232 for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1233 UpdateWindowTree(*iter);
1234 }
1235 return;
1236 }
1237
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1238 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1239 {
1240 if (windowNodes.empty()) {
1241 WLOGFE("windowNodes is empty!");
1242 return;
1243 }
1244 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1245 [windowId](sptr<WindowNode> node) {
1246 return node->GetWindowId() == windowId;
1247 });
1248 // raise app node window to top
1249 if (iter != windowNodes.end()) {
1250 sptr<WindowNode> node = *iter;
1251 windowNodes.erase(iter);
1252 UpdateWindowTree(node);
1253 WLOGFI("raise window to top %{public}u", node->GetWindowId());
1254 }
1255 }
1256
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1257 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1258 {
1259 for (auto& node : belowAppWindowNode_->children_) {
1260 TraverseWindowNode(node, windowNodes);
1261 }
1262 for (auto& node : appWindowNode_->children_) {
1263 TraverseWindowNode(node, windowNodes);
1264 }
1265 for (auto& node : aboveAppWindowNode_->children_) {
1266 TraverseWindowNode(node, windowNodes);
1267 }
1268 std::reverse(windowNodes.begin(), windowNodes.end());
1269 }
1270
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1271 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1272 {
1273 if (node == nullptr) {
1274 return;
1275 }
1276 auto iter = node->children_.begin();
1277 for (; iter < node->children_.end(); ++iter) {
1278 if ((*iter)->priority_ < 0) {
1279 windowNodes.emplace_back(*iter);
1280 } else {
1281 break;
1282 }
1283 }
1284 windowNodes.emplace_back(node);
1285 for (; iter < node->children_.end(); ++iter) {
1286 windowNodes.emplace_back(*iter);
1287 }
1288 }
1289
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType) const1290 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1291 {
1292 if (CheckWindowNodeWhetherInWindowTree(node)) {
1293 return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1294 }
1295 return {};
1296 }
1297
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1298 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1299 {
1300 bool isInWindowTree = false;
1301 WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1302 if (node->GetWindowId() == windowNode->GetWindowId()) {
1303 isInWindowTree = true;
1304 return true;
1305 }
1306 return false;
1307 };
1308 TraverseWindowTree(func, true);
1309 return isInWindowTree;
1310 }
1311
DumpScreenWindowTree()1312 void WindowNodeContainer::DumpScreenWindowTree()
1313 {
1314 WLOGFI("-------- dump window info begin---------");
1315 WLOGFI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation abilityToken [ x y w h]");
1316 uint32_t zOrder = zOrder_;
1317 WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1318 Rect rect = node->GetWindowRect();
1319 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1320 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1321 WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1322 "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1323 windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1324 node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1325 node->abilityToken_ != nullptr, rect.posX_, rect.posY_, rect.width_, rect.height_);
1326 return false;
1327 };
1328 TraverseWindowTree(func, true);
1329 WLOGFI("-------- dump window info end ---------");
1330 }
1331
GetDisplayRect(DisplayId displayId) const1332 Rect WindowNodeContainer::GetDisplayRect(DisplayId displayId) const
1333 {
1334 return displayGroupInfo_->GetDisplayRect(displayId);
1335 }
1336
IsVerticalDisplay(DisplayId displayId) const1337 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1338 {
1339 return displayGroupInfo_->GetDisplayRect(displayId).width_ < displayGroupInfo_->GetDisplayRect(displayId).height_;
1340 }
1341
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1342 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1343 {
1344 switch (reason) {
1345 case WindowStateChangeReason::KEYGUARD: {
1346 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1347 TraverseAndUpdateWindowState(state, topPriority);
1348 break;
1349 }
1350 default:
1351 return;
1352 }
1353 }
1354
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1355 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1356 {
1357 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1358 for (auto& node : rootNodes) {
1359 UpdateWindowState(node, topPriority, state);
1360 }
1361 }
1362
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1363 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1364 {
1365 if (node == nullptr) {
1366 return;
1367 }
1368 if (node->parent_ != nullptr && node->currentVisibility_) {
1369 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1370 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1371 if (node->GetWindowToken()) {
1372 node->GetWindowToken()->UpdateWindowState(state);
1373 }
1374 HandleKeepScreenOn(node, state);
1375 }
1376 }
1377 for (auto& childNode : node->children_) {
1378 UpdateWindowState(childNode, topPriority, state);
1379 }
1380 }
1381
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1382 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1383 {
1384 if (node == nullptr) {
1385 WLOGFE("window is invalid");
1386 return;
1387 }
1388 if (state == WindowState::STATE_FROZEN) {
1389 HandleKeepScreenOn(node, false);
1390 } else if (state == WindowState::STATE_UNFROZEN) {
1391 HandleKeepScreenOn(node, node->IsKeepScreenOn());
1392 } else {
1393 // do nothing
1394 }
1395 }
1396
FindDividerNode() const1397 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1398 {
1399 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1400 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1401 return *iter;
1402 }
1403 }
1404 return nullptr;
1405 }
1406
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1407 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1408 {
1409 if (node == nullptr) {
1410 return;
1411 }
1412 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1413 if (windowPair == nullptr) {
1414 WLOGFE("Window pair is nullptr");
1415 return;
1416 }
1417 std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1418 RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1419 AssignZOrder();
1420 return;
1421 }
1422
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1423 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1424 {
1425 if (node == nullptr) {
1426 return WMError::WM_ERROR_NULLPTR;
1427 }
1428 if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1429 WLOGFI("it is already top app window, id: %{public}u", node->GetWindowId());
1430 return WMError::WM_ERROR_INVALID_TYPE;
1431 }
1432
1433 if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1434 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1435 if (parentNode == nullptr) {
1436 WLOGFE("window type is invalid");
1437 return WMError::WM_ERROR_NULLPTR;
1438 }
1439 RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1440 if (parentNode->IsSplitMode()) {
1441 RaiseSplitRelatedWindowToTop(parentNode);
1442 } else if (parentNode->parent_ != nullptr) {
1443 RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1444 }
1445 } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1446 if (node->IsSplitMode()) {
1447 RaiseSplitRelatedWindowToTop(node);
1448 } else {
1449 // remote animation continuous start and exit allow parent is nullptr
1450 if (node->parent_ == nullptr) {
1451 WLOGFW("node parent is nullptr");
1452 return WMError::WM_OK;
1453 }
1454 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1455 }
1456 } else {
1457 // do nothing
1458 }
1459 AssignZOrder();
1460 WLOGFI("RaiseZOrderForAppWindow finished");
1461 DumpScreenWindowTree();
1462 return WMError::WM_OK;
1463 }
1464
GetNextFocusableWindow(uint32_t windowId) const1465 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1466 {
1467 sptr<WindowNode> nextFocusableWindow;
1468 bool previousFocusedWindowFound = false;
1469 WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1470 sptr<WindowNode> node) {
1471 if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1472 nextFocusableWindow = node;
1473 return true;
1474 }
1475 if (node->GetWindowId() == windowId) {
1476 previousFocusedWindowFound = true;
1477 }
1478 return false;
1479 };
1480 TraverseWindowTree(func, true);
1481 return nextFocusableWindow;
1482 }
1483
GetNextRotatableWindow(uint32_t windowId) const1484 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1485 {
1486 sptr<WindowNode> nextRotatableWindow;
1487 WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1488 sptr<WindowNode> node) {
1489 if (windowId != node->GetWindowId() &&
1490 WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1491 nextRotatableWindow = node;
1492 return true;
1493 }
1494 return false;
1495 };
1496 TraverseWindowTree(func, true);
1497 return nextRotatableWindow;
1498 }
1499
GetNextActiveWindow(uint32_t windowId) const1500 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1501 {
1502 auto currentNode = FindWindowNodeById(windowId);
1503 if (currentNode == nullptr) {
1504 WLOGFE("cannot find window id: %{public}u by tree", windowId);
1505 return nullptr;
1506 }
1507 WLOGFI("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1508 if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1509 for (auto& node : appWindowNode_->children_) {
1510 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1511 continue;
1512 }
1513 return node;
1514 }
1515 for (auto& node : belowAppWindowNode_->children_) {
1516 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1517 return node;
1518 }
1519 }
1520 } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1521 std::vector<sptr<WindowNode>> windowNodes;
1522 TraverseContainer(windowNodes);
1523 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1524 return node->GetWindowId() == windowId;
1525 });
1526 if (iter == windowNodes.end()) {
1527 WLOGFE("could not find this window");
1528 return nullptr;
1529 }
1530 int index = std::distance(windowNodes.begin(), iter);
1531 for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1532 if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1533 || !windowNodes[i]->currentVisibility_) {
1534 continue;
1535 }
1536 return windowNodes[i];
1537 }
1538 } else {
1539 // do nothing
1540 }
1541 WLOGFE("could not get next active window");
1542 return nullptr;
1543 }
1544
IsForbidDockSliceMove(DisplayId displayId) const1545 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1546 {
1547 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1548 if (windowPair == nullptr) {
1549 WLOGFE("window pair is nullptr");
1550 return true;
1551 }
1552 if (windowPair->IsForbidDockSliceMove()) {
1553 return true;
1554 }
1555 return false;
1556 }
1557
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1558 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1559 {
1560 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1561 if (windowPair == nullptr) {
1562 WLOGFE("window pair is nullptr");
1563 return false;
1564 }
1565 std::vector<int32_t> exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId);
1566 if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1567 return false;
1568 }
1569 return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1570 }
1571
ExitSplitMode(DisplayId displayId)1572 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1573 {
1574 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1575 if (windowPair == nullptr) {
1576 WLOGFE("window pair is nullptr");
1577 return;
1578 }
1579 windowPair->ExitSplitMode();
1580 }
1581
MinimizeAllAppWindows(DisplayId displayId)1582 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1583 {
1584 WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1585 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1586 if (ret != WMError::WM_OK) {
1587 WLOGFE("Minimize all app window failed");
1588 }
1589 return;
1590 }
1591
GetDeskTopWindow()1592 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1593 {
1594 sptr<WindowNode> deskTop;
1595 WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1596 if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1597 deskTop = node;
1598 return true;
1599 }
1600 return false;
1601 };
1602 TraverseWindowTree(findDeskTopFunc, false);
1603 return deskTop;
1604 }
1605
HasPrivateWindow()1606 bool WindowNodeContainer::HasPrivateWindow()
1607 {
1608 std::vector<sptr<WindowNode>> windowNodes;
1609 TraverseContainer(windowNodes);
1610 for (const auto& node : windowNodes) {
1611 if (node->isVisible_ && node->GetWindowProperty()->GetPrivacyMode()) {
1612 WLOGFI("window name %{public}s", node->GetWindowName().c_str());
1613 return true;
1614 }
1615 }
1616 return false;
1617 }
1618
MinimizeOldestAppWindow()1619 void WindowNodeContainer::MinimizeOldestAppWindow()
1620 {
1621 for (auto& appNode : appWindowNode_->children_) {
1622 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1623 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1624 return;
1625 }
1626 }
1627 for (auto& appNode : aboveAppWindowNode_->children_) {
1628 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1629 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
1630 return;
1631 }
1632 }
1633 WLOGFI("no window needs to minimize");
1634 }
1635
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)1636 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
1637 std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
1638 {
1639 WLOGFI("ToggleShownStateForAllAppWindows");
1640 for (auto node : aboveAppWindowNode_->children_) {
1641 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
1642 node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
1643 return WMError::WM_DO_NOTHING;
1644 }
1645 }
1646 // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
1647 if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
1648 backupWindowIds_.clear();
1649 backupWindowMode_.clear();
1650 backupDisplaySplitWindowMode_.clear();
1651 backupDividerWindowRect_.clear();
1652 }
1653 if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
1654 WLOGFI("backup");
1655 BackUpAllAppWindows();
1656 } else if (restore && !backupWindowIds_.empty()) {
1657 WLOGFI("restore");
1658 RestoreAllAppWindows(restoreFunc);
1659 } else {
1660 WLOGFI("do nothing because shown app windows is empty or backup windows is empty.");
1661 }
1662 return WMError::WM_OK;
1663 }
1664
BackUpAllAppWindows()1665 void WindowNodeContainer::BackUpAllAppWindows()
1666 {
1667 std::set<DisplayId> displayIdSet;
1668 backupWindowMode_.clear();
1669 backupDisplaySplitWindowMode_.clear();
1670 std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
1671 for (auto& appNode : children) {
1672 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1673 continue;
1674 }
1675 auto windowMode = appNode->GetWindowMode();
1676 backupWindowMode_[appNode->GetWindowId()] = windowMode;
1677 if (WindowHelper::IsSplitWindowMode(windowMode)) {
1678 backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
1679 }
1680 displayIdSet.insert(appNode->GetDisplayId());
1681 }
1682 for (auto& appNode : children) {
1683 // exclude exceptional window
1684 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
1685 WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
1686 continue;
1687 }
1688 // minimize window
1689 WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
1690 backupWindowIds_.emplace_back(appNode->GetWindowId());
1691 WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId());
1692 wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
1693 WindowInnerManager::GetInstance().PostTask([abilityToken]() {
1694 auto token = abilityToken.promote();
1695 if (token == nullptr) {
1696 WLOGFW("Ability token is null");
1697 return;
1698 }
1699 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
1700 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
1701 });
1702 }
1703 backupDividerWindowRect_.clear();
1704 for (auto displayId : displayIdSet) {
1705 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1706 if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
1707 continue;
1708 }
1709 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
1710 }
1711 }
1712
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)1713 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
1714 {
1715 std::vector<uint32_t> backupWindowIds(backupWindowIds_);
1716 auto displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds();
1717 std::vector<sptr<WindowPair>> windowPairs;
1718 for (auto displayId : displayIds) {
1719 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1720 if (windowPair != nullptr) {
1721 if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
1722 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
1723 windowPair->SetAllSplitAppWindowsRestoring(true);
1724 }
1725 windowPairs.emplace_back(windowPair);
1726 }
1727 }
1728 for (auto windowId: backupWindowIds) {
1729 if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
1730 WLOGFE("restore %{public}u failed", windowId);
1731 continue;
1732 }
1733 WLOGFD("restore %{public}u", windowId);
1734 }
1735 for (auto windowPair : windowPairs) {
1736 windowPair->SetAllSplitAppWindowsRestoring(false);
1737 }
1738 layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
1739 backupWindowIds_.clear();
1740 backupWindowMode_.clear();
1741 backupDividerWindowRect_.clear();
1742 }
1743
IsAppWindowsEmpty() const1744 bool WindowNodeContainer::IsAppWindowsEmpty() const
1745 {
1746 return appWindowNode_->children_.empty();
1747 }
1748
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)1749 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
1750 const std::vector<uint32_t> &exceptionalIds, const std::vector<WindowMode> &exceptionalModes)
1751 {
1752 if (appWindowNode_->children_.empty()) {
1753 return WMError::WM_OK;
1754 }
1755 for (auto& appNode : appWindowNode_->children_) {
1756 // exclude exceptional window
1757 if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
1758 std::find(exceptionalModes.begin(), exceptionalModes.end(),
1759 appNode->GetWindowMode()) != exceptionalModes.end() ||
1760 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1761 continue;
1762 }
1763 MinimizeApp::AddNeedMinimizeApp(appNode, reason);
1764 }
1765 return WMError::WM_OK;
1766 }
1767
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)1768 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
1769 {
1770 std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
1771 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
1772 return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
1773 }
1774
ResetLayoutPolicy()1775 void WindowNodeContainer::ResetLayoutPolicy()
1776 {
1777 layoutPolicy_->Reset();
1778 }
1779
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)1780 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
1781 {
1782 WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
1783 static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
1784 if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
1785 WLOGFE("invalid layout mode");
1786 return WMError::WM_ERROR_INVALID_PARAM;
1787 }
1788 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1789 if (windowPair == nullptr) {
1790 WLOGFE("Window pair is nullptr");
1791 return WMError::WM_ERROR_NULLPTR;
1792 }
1793 if (layoutMode_ != dstMode) {
1794 if (layoutMode_ == WindowLayoutMode::CASCADE) {
1795 layoutPolicy_->Reset();
1796 windowPair->Clear();
1797 }
1798 layoutMode_ = dstMode;
1799 layoutPolicy_->Clean();
1800 layoutPolicy_ = layoutPolicies_[dstMode];
1801 layoutPolicy_->Launch();
1802 DumpScreenWindowTree();
1803 } else {
1804 WLOGFI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
1805 }
1806 if (reorder) {
1807 windowPair->Clear();
1808 layoutPolicy_->Reorder();
1809 DumpScreenWindowTree();
1810 }
1811 NotifyIfSystemBarTintChanged(displayId);
1812 return WMError::WM_OK;
1813 }
1814
UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode> & node,bool up)1815 void WindowNodeContainer::UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
1816 {
1817 if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestModeSupportInfo(),
1818 WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1819 WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
1820 return;
1821 }
1822 uint32_t modeSupportInfo;
1823 if (up) {
1824 modeSupportInfo = node->GetModeSupportInfo() & (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1825 } else {
1826 modeSupportInfo = node->GetModeSupportInfo() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
1827 }
1828 node->SetModeSupportInfo(modeSupportInfo);
1829 if (node->GetWindowToken() != nullptr) {
1830 node->GetWindowToken()->UpdateWindowModeSupportInfo(modeSupportInfo);
1831 }
1832 }
1833
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const1834 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
1835 {
1836 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || !isScreenLocked_) {
1837 return;
1838 }
1839
1840 WLOGFI("raise input method float window priority.");
1841 node->priority_ = zorderPolicy_->GetWindowPriority(
1842 WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
1843 }
1844
ReZOrderShowWhenLockedWindows(bool up)1845 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
1846 {
1847 WLOGFI("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
1848 std::vector<sptr<WindowNode>> needReZOrderNodes;
1849 auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
1850 auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
1851
1852 auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
1853 zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
1854
1855 for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
1856 if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
1857 needReZOrderNodes.emplace_back(*iter);
1858 iter = srcRoot->children_.erase(iter);
1859 } else {
1860 iter++;
1861 }
1862 }
1863
1864 for (auto& needReZOrderNode : needReZOrderNodes) {
1865 needReZOrderNode->priority_ = dstPriority;
1866 needReZOrderNode->parent_ = dstRoot;
1867 auto parentNode = needReZOrderNode->parent_;
1868 auto position = parentNode->children_.end();
1869 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
1870 if ((*iter)->priority_ > needReZOrderNode->priority_) {
1871 position = iter;
1872 break;
1873 }
1874 }
1875
1876 UpdateModeSupportInfoWhenKeyguardChange(needReZOrderNode, up);
1877
1878 parentNode->children_.insert(position, needReZOrderNode);
1879 if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
1880 needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
1881 if (needReZOrderNode->GetWindowToken() != nullptr) {
1882 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
1883 }
1884 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
1885 if (windowPair == nullptr) {
1886 WLOGFE("Window pair is nullptr");
1887 return;
1888 }
1889 windowPair->UpdateIfSplitRelated(needReZOrderNode);
1890 }
1891 WLOGFI("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
1892 }
1893 }
1894
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1895 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1896 {
1897 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1898 !isScreenLocked_) {
1899 return;
1900 }
1901
1902 WLOGFI("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
1903 ReZOrderShowWhenLockedWindows(true);
1904 }
1905
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1906 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1907 {
1908 // if keyguard window show, raise show when locked windows
1909 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1910 ReZOrderShowWhenLockedWindows(true);
1911 return;
1912 }
1913
1914 // if show when locked window show, raise itself when exist keyguard
1915 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
1916 !isScreenLocked_) {
1917 return;
1918 }
1919
1920 WLOGFI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
1921 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
1922 node->parent_ = aboveAppWindowNode_;
1923 if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
1924 node->GetWindowProperty()->ResumeLastWindowMode();
1925 if (node->GetWindowToken() != nullptr) {
1926 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
1927 }
1928 }
1929 }
1930
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)1931 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
1932 {
1933 // if keyguard window hide, drop show when locked windows
1934 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
1935 ReZOrderShowWhenLockedWindows(false);
1936 AssignZOrder();
1937 }
1938 }
1939
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const1940 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
1941 {
1942 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1943 if (isFromTopToBottom) {
1944 std::reverse(rootNodes.begin(), rootNodes.end());
1945 }
1946
1947 for (const auto& node : rootNodes) {
1948 if (isFromTopToBottom) {
1949 for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
1950 if (TraverseFromTopToBottom(*iter, func)) {
1951 return;
1952 }
1953 }
1954 } else {
1955 for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
1956 if (TraverseFromBottomToTop(*iter, func)) {
1957 return;
1958 }
1959 }
1960 }
1961 }
1962 }
1963
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1964 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1965 {
1966 if (node == nullptr) {
1967 return false;
1968 }
1969 auto iterBegin = node->children_.rbegin();
1970 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1971 if ((*iterBegin)->priority_ <= 0) {
1972 break;
1973 }
1974 if (func(*iterBegin)) {
1975 return true;
1976 }
1977 }
1978 if (func(node)) {
1979 return true;
1980 }
1981 for (; iterBegin != node->children_.rend(); ++iterBegin) {
1982 if (func(*iterBegin)) {
1983 return true;
1984 }
1985 }
1986 return false;
1987 }
1988
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const1989 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
1990 {
1991 if (node == nullptr) {
1992 return false;
1993 }
1994 auto iterBegin = node->children_.begin();
1995 for (; iterBegin != node->children_.end(); ++iterBegin) {
1996 if ((*iterBegin)->priority_ >= 0) {
1997 break;
1998 }
1999 if (func(*iterBegin)) {
2000 return true;
2001 }
2002 }
2003 if (func(node)) {
2004 return true;
2005 }
2006 for (; iterBegin != node->children_.end(); ++iterBegin) {
2007 if (func(*iterBegin)) {
2008 return true;
2009 }
2010 }
2011 return false;
2012 }
2013
GetVirtualPixelRatio(DisplayId displayId) const2014 float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const
2015 {
2016 return layoutPolicy_->GetVirtualPixelRatio(displayId);
2017 }
2018
GetDisplayGroupRect() const2019 Rect WindowNodeContainer::GetDisplayGroupRect() const
2020 {
2021 return layoutPolicy_->GetDisplayGroupRect();
2022 }
2023
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2024 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2025 {
2026 if (node == nullptr) {
2027 WLOGFE("could not find window");
2028 return WMError::WM_ERROR_NULLPTR;
2029 }
2030 WindowMode srcMode = node->GetWindowMode();
2031 if (srcMode == dstMode) {
2032 return WMError::WM_OK;
2033 }
2034
2035 if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2036 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2037 return WMError::WM_ERROR_INVALID_PARAM;
2038 }
2039
2040 WMError res = WMError::WM_OK;
2041 if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2042 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2043 } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2044 node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2045 if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2046 node->SetRequestRect(node->GetWindowRect());
2047 }
2048 } else {
2049 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2050 }
2051 node->SetWindowMode(dstMode);
2052 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2053 if (windowPair == nullptr) {
2054 WLOGFE("Window pair is nullptr");
2055 return WMError::WM_ERROR_NULLPTR;
2056 }
2057 windowPair->UpdateIfSplitRelated(node);
2058 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2059 if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2060 NotifyDockWindowStateChanged(node, true);
2061 } else {
2062 NotifyDockWindowStateChanged(node, false);
2063 }
2064 }
2065
2066 if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2067 WindowHelper::IsAppWindow(node->GetWindowType())) {
2068 // minimize other app window
2069 res = MinimizeStructuredAppWindowsExceptSelf(node);
2070 if (res != WMError::WM_OK) {
2071 return res;
2072 }
2073 }
2074 if (node->GetWindowToken() != nullptr) {
2075 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2076 }
2077 res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2078 if (res != WMError::WM_OK) {
2079 WLOGFE("Set window mode failed, update node failed");
2080 return res;
2081 }
2082 return WMError::WM_OK;
2083 }
2084
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2085 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2086 const ModeChangeHotZonesConfig& config)
2087 {
2088 const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId);
2089
2090 hotZones.fullscreen_.width_ = displayRect.width_;
2091 hotZones.fullscreen_.height_ = config.fullscreenRange_;
2092
2093 hotZones.primary_.width_ = config.primaryRange_;
2094 hotZones.primary_.height_ = displayRect.height_;
2095
2096 hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2097 hotZones.secondary_.width_ = config.secondaryRange_;
2098 hotZones.secondary_.height_ = displayRect.height_;
2099 }
2100
GetDisplayVirtualPixelRatio(DisplayId displayId) const2101 float WindowNodeContainer::GetDisplayVirtualPixelRatio(DisplayId displayId) const
2102 {
2103 return displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId);
2104 }
2105
GetDisplayInfo(DisplayId displayId)2106 sptr<DisplayInfo> WindowNodeContainer::GetDisplayInfo(DisplayId displayId)
2107 {
2108 return displayGroupInfo_->GetDisplayInfo(displayId);
2109 }
2110
UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)2111 void WindowNodeContainer::UpdateDisplayInfo(sptr<DisplayInfo> displayInfo)
2112 {
2113 displayGroupInfo_->UpdateDisplayInfo(displayInfo);
2114 }
2115
GetAllDisplayInfo()2116 std::vector<sptr<DisplayInfo>> WindowNodeContainer::GetAllDisplayInfo()
2117 {
2118 return displayGroupInfo_->GetAllDisplayInfo();
2119 }
2120
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2121 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2122 {
2123 if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2124 WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2125 }
2126 }
2127
GetCurrentLayoutMode() const2128 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2129 {
2130 return layoutMode_;
2131 }
2132
RemoveSingleUserWindowNodes(int accountId)2133 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2134 {
2135 std::vector<sptr<WindowNode>> windowNodes;
2136 TraverseContainer(windowNodes);
2137 WLOGFI("%{public}d", accountId);
2138 for (auto& windowNode : windowNodes) {
2139 int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2140 if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2141 WLOGFI("skiped window %{public}s, windowId %{public}d uid %{public}d",
2142 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2143 continue;
2144 }
2145 WLOGFI("remove window %{public}s, windowId %{public}d uid %{public}d",
2146 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2147 windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2148 if (windowNode->GetWindowToken()) {
2149 if (windowNode->surfaceNode_ != nullptr) {
2150 windowNode->surfaceNode_->SetVisible(true);
2151 }
2152 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2153 }
2154 }
2155 }
2156
TakeWindowPairSnapshot(DisplayId displayId)2157 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2158 {
2159 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2160 return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2161 }
2162
ClearWindowPairSnapshot(DisplayId displayId)2163 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2164 {
2165 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2166 if (windowPair == nullptr) {
2167 WLOGFE("Window pair is nullptr");
2168 return;
2169 }
2170 windowPair->ClearPairSnapshot();
2171 }
2172
IsScreenLocked()2173 bool WindowNodeContainer::IsScreenLocked()
2174 {
2175 return isScreenLocked_;
2176 }
2177 } // namespace Rosen
2178 } // namespace OHOS
2179