1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "window_node_container.h"
17
18 #include <ability_manager_client.h>
19 #include <algorithm>
20 #include <cinttypes>
21 #include <cmath>
22 #include <ctime>
23 #include <hitrace_meter.h>
24 #include <limits>
25 #include <transaction/rs_interfaces.h>
26 #include <transaction/rs_transaction.h>
27 #include <transaction/rs_sync_transaction_controller.h>
28
29 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
30 #include <display_power_mgr_client.h>
31 #endif
32
33 #ifdef POWER_MANAGER_ENABLE
34 #include <power_mgr_client.h>
35 #endif
36
37 #include "common_event_manager.h"
38 #include "dm_common.h"
39 #include "remote_animation.h"
40 #include "starting_window.h"
41 #include "window_helper.h"
42 #include "window_inner_manager.h"
43 #include "window_layout_policy_cascade.h"
44 #include "window_layout_policy_tile.h"
45 #include "window_manager_agent_controller.h"
46 #include "window_manager_hilog.h"
47 #include "window_manager_service.h"
48 #include "window_manager_service_utils.h"
49 #include "window_system_effect.h"
50 #include "wm_common.h"
51 #include "wm_common_inner.h"
52
53 namespace OHOS {
54 namespace Rosen {
55 namespace {
56 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Container"};
57 constexpr int WINDOW_NAME_MAX_LENGTH = 10;
58 constexpr uint32_t MAX_BRIGHTNESS = 255;
59 constexpr uint32_t SPLIT_WINDOWS_CNT = 2;
60 constexpr uint32_t EXIT_SPLIT_POINTS_NUMBER = 2;
61 constexpr int UID_TRANSFROM_DIVISOR = 200000;
62 constexpr int UID_MIN = 100;
63 }
64 AnimationConfig WindowNodeContainer::animationConfig_;
65 bool WindowNodeContainer::isFloatWindowAboveFullWindow_ = false;
66 uint32_t WindowNodeContainer::maxMainFloatingWindowNumber_ = 100;
67 bool WindowNodeContainer::isAnimateTransactionEnabled_ = false;
68 std::string WindowNodeContainer::uiType_ = "";
69
WindowNodeContainer(const sptr<DisplayInfo> & displayInfo,ScreenId displayGroupId)70 WindowNodeContainer::WindowNodeContainer(const sptr<DisplayInfo>& displayInfo, ScreenId displayGroupId)
71 {
72 DisplayId displayId = displayInfo->GetDisplayId();
73
74 // create and displayGroupInfo and displayGroupController
75 DisplayGroupInfo::GetInstance().Init(displayGroupId, displayInfo);
76 displayGroupController_ = new DisplayGroupController(this);
77 displayGroupController_->InitNewDisplay(displayId);
78
79 // init layout policy
80 layoutPolicies_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(
81 displayGroupController_->displayGroupWindowTree_);
82 layoutPolicies_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(
83 displayGroupController_->displayGroupWindowTree_);
84 layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE];
85 layoutPolicy_->Launch();
86
87 // set initial divider rect in windowPair
88 Rect initialDivRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId);
89 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
90 if (windowPair != nullptr) {
91 windowPair->SetDividerRect(initialDivRect);
92 }
93
94 // init avoidAreaController
95 avoidController_ = new AvoidAreaController(focusedWindow_);
96 WindowInnerManager::GetInstance().NotifyDisplayLimitRectChange(
97 DisplayGroupInfo::GetInstance().GetAllDisplayRects());
98 isAnimateTransactionEnabled_ = system::GetParameter("persist.window.animateTransaction.enabled", "1") == "1";
99 }
100
~WindowNodeContainer()101 WindowNodeContainer::~WindowNodeContainer()
102 {
103 Destroy();
104 }
105
GetWindowCountByType(WindowType windowType)106 uint32_t WindowNodeContainer::GetWindowCountByType(WindowType windowType)
107 {
108 uint32_t windowNumber = 0;
109 auto counter = [&windowNumber, &windowType](sptr<WindowNode>& windowNode) {
110 if (windowNode->GetWindowType() == windowType && !windowNode->startingWindowShown_) {
111 ++windowNumber;
112 }
113 };
114 std::for_each(belowAppWindowNode_->children_.begin(), belowAppWindowNode_->children_.end(), counter);
115 std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
116 std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
117 return windowNumber;
118 }
119
GetMainFloatingWindowCount()120 uint32_t WindowNodeContainer::GetMainFloatingWindowCount()
121 {
122 uint32_t windowNumber = 0;
123 auto counter = [&windowNumber](sptr<WindowNode>& windowNode) {
124 WindowType windowType = windowNode->GetWindowType();
125 WindowMode windowMode = windowNode->GetWindowMode();
126 if (WindowHelper::IsMainFloatingWindow(windowType, windowMode) &&
127 !windowNode->startingWindowShown_) {
128 ++windowNumber;
129 }
130 };
131 std::for_each(appWindowNode_->children_.begin(), appWindowNode_->children_.end(), counter);
132 std::for_each(aboveAppWindowNode_->children_.begin(), aboveAppWindowNode_->children_.end(), counter);
133 return windowNumber;
134 }
135
AddWindowNodeOnWindowTree(sptr<WindowNode> & node,const sptr<WindowNode> & parentNode)136 WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr<WindowNode>& node, const sptr<WindowNode>& parentNode)
137 {
138 sptr<WindowNode> root = FindRoot(node->GetWindowType());
139 if (root == nullptr && !(WindowHelper::IsSystemSubWindow(node->GetWindowType()) &&
140 parentNode != nullptr)) {
141 WLOGFE("root is nullptr!");
142 return WMError::WM_ERROR_NULLPTR;
143 }
144 node->requestedVisibility_ = true;
145 if (parentNode != nullptr) { // subwindow
146 if (WindowHelper::IsSystemSubWindow(node->GetWindowType()) ||
147 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
148 if (WindowHelper::IsSubWindow(parentNode->GetWindowType()) ||
149 WindowHelper::IsSystemSubWindow(parentNode->GetWindowType()) ||
150 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT ||
151 parentNode->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
152 // some times, dialog is a child window, so exclude
153 WLOGFE("the parent of window cannot be any sub window");
154 return WMError::WM_ERROR_INVALID_PARAM;
155 }
156 } else {
157 if (parentNode->parent_ != root &&
158 !((parentNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) &&
159 (parentNode->parent_ == aboveAppWindowNode_))) {
160 WLOGFE("window type and parent window not match \
161 or try to add subwindow to subwindow, which is forbidden");
162 return WMError::WM_ERROR_INVALID_PARAM;
163 }
164 }
165 node->currentVisibility_ = parentNode->currentVisibility_;
166 node->parent_ = parentNode;
167 } else { // mainwindow
168 node->parent_ = root;
169 node->currentVisibility_ = true;
170 for (auto& child : node->children_) {
171 child->currentVisibility_ = child->requestedVisibility_;
172 }
173 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
174 displayGroupController_->sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node;
175 }
176 }
177 return WMError::WM_OK;
178 }
179
ShowStartingWindow(sptr<WindowNode> & node)180 WMError WindowNodeContainer::ShowStartingWindow(sptr<WindowNode>& node)
181 {
182 if (node->currentVisibility_) {
183 WLOGFE("current window is visible, windowId: %{public}u", node->GetWindowId());
184 return WMError::WM_ERROR_INVALID_OPERATION;
185 }
186
187 WMError res = AddWindowNodeOnWindowTree(node, nullptr);
188 if (res != WMError::WM_OK) {
189 return res;
190 }
191 UpdateWindowTree(node);
192 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
193 StartingWindow::AddNodeOnRSTree(node, layoutPolicy_->IsMultiDisplay());
194 AssignZOrder();
195 layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
196 WLOGI("ShowStartingWindow windowId: %{public}u end", node->GetWindowId());
197 return WMError::WM_OK;
198 }
199
IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode> & node)200 WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr<WindowNode>& node)
201 {
202 if (layoutMode_ == WindowLayoutMode::TILE &&
203 !layoutPolicy_->IsTileRectSatisfiedWithSizeLimits(node)) {
204 WLOGFE("layoutMode is tile, default rect is not satisfied with size limits of window, windowId: %{public}u",
205 node->GetWindowId());
206 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
207 }
208 return WMError::WM_OK;
209 }
210
GetAnimationConfigRef()211 AnimationConfig& WindowNodeContainer::GetAnimationConfigRef()
212 {
213 return animationConfig_;
214 }
215
LayoutWhenAddWindowNode(sptr<WindowNode> & node,bool afterAnimation)216 void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool afterAnimation)
217 {
218 if (afterAnimation) {
219 layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
220 return;
221 }
222 WLOGFD("AddWindowNode Id:%{public}u, currState:%{public}u",
223 node->GetWindowId(), static_cast<uint32_t>(node->stateMachine_.GetCurrentState()));
224 if (WindowHelper::IsMainWindow(node->GetWindowType()) &&
225 RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
226 node->stateMachine_.IsShowAnimationPlaying()) {
227 // for first frame callback
228 auto winRect = node->GetWindowRect();
229 if (node->surfaceNode_) {
230 node->surfaceNode_->SetBounds(0, 0, winRect.width_, winRect.height_);
231 WLOGI("SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]",
232 node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
233 layoutPolicy_->NotifyClientAndAnimation(node, winRect, WindowSizeChangeReason::UNDEFINED);
234 }
235 } else {
236 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
237 WindowHelper::IsSystemWindow(node->GetWindowType())) {
238 node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW);
239 }
240 layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
241 }
242 }
243
AddWindowNode(sptr<WindowNode> & node,sptr<WindowNode> & parentNode,bool afterAnimation)244 WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNode>& parentNode, bool afterAnimation)
245 {
246 if (!node->startingWindowShown_) { // window except main Window
247 WMError res = AddWindowNodeOnWindowTree(node, parentNode);
248 if (res != WMError::WM_OK) {
249 return res;
250 }
251 UpdateWindowTree(node);
252 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
253 // add node on RSTree
254 for (auto& displayId : node->GetShowingDisplays()) {
255 AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ADDED,
256 node->isPlayAnimationShow_);
257 }
258 } else { // only main app window has starting window
259 node->isPlayAnimationShow_ = false;
260 node->startingWindowShown_ = false;
261 AddAppSurfaceNodeOnRSTree(node);
262 ReZOrderShowWhenLockedWindowIfNeeded(node);
263 RaiseZOrderForAppWindow(node, parentNode);
264 }
265 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
266 if (windowPair == nullptr) {
267 WLOGFE("Window pair is nullptr");
268 return WMError::WM_ERROR_NULLPTR;
269 }
270 windowPair->UpdateIfSplitRelated(node);
271 if (node->IsSplitMode()) {
272 // raise the z-order of window pair
273 RaiseSplitRelatedWindowToTop(node);
274 if (isFloatWindowAboveFullWindow_ && !windowPair->IsDuringSplit()) {
275 ResetAllMainFloatingWindowZOrder(appWindowNode_);
276 }
277 }
278 MinimizeOldestMainFloatingWindow(node->GetWindowId());
279 AssignZOrder();
280 LayoutWhenAddWindowNode(node, afterAnimation);
281 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
282 DumpScreenWindowTreeByWinId(node->GetWindowId());
283 UpdateCameraFloatWindowStatus(node, true);
284 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
285 backupWindowIds_.clear();
286 }
287
288 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
289 isScreenLocked_ = true;
290 SetBelowScreenlockVisible(node, false);
291 }
292 if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
293 RemoteAnimation::NotifyAnimationUpdateWallpaper(node);
294 }
295 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
296 DisplayManagerServiceInner::GetInstance().SetGravitySensorSubscriptionEnabled();
297 }
298 WLOGI("AddWindowNode Id: %{public}u end", node->GetWindowId());
299 RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
300 // update private window count and notify dms private status changed
301 if (node->GetWindowProperty()->GetPrivacyMode()) {
302 UpdatePrivateStateAndNotify();
303 }
304 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
305 WindowInfoReporter::GetInstance().InsertShowReportInfo(node->abilityInfo_.bundleName_);
306 }
307 return WMError::WM_OK;
308 }
309
UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode> & node,const std::vector<DisplayId> & lastShowingDisplays)310 void WindowNodeContainer::UpdateRSTreeWhenShowingDisplaysChange(sptr<WindowNode>& node,
311 const std::vector<DisplayId>& lastShowingDisplays)
312 {
313 if (!layoutPolicy_->IsMultiDisplay()) {
314 return;
315 }
316
317 // Update RSTree
318 auto curShowingDisplays = node->GetShowingDisplays();
319 for (auto& displayId : lastShowingDisplays) {
320 if (std::find(curShowingDisplays.begin(), curShowingDisplays.end(), displayId) == curShowingDisplays.end()) {
321 RemoveNodeFromRSTree(node, displayId, *(curShowingDisplays.begin()),
322 WindowUpdateType::WINDOW_UPDATE_ACTIVE);
323 WLOGI("remove from RSTree : %{public}" PRIu64"", displayId);
324 }
325 }
326
327 for (auto& displayId : curShowingDisplays) {
328 if (std::find(lastShowingDisplays.begin(), lastShowingDisplays.end(), displayId) == lastShowingDisplays.end()) {
329 AddNodeOnRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
330 WLOGI("add on RSTree : %{public}" PRIu64"", displayId);
331 }
332 }
333 }
334
UpdateWindowNode(sptr<WindowNode> & node,WindowUpdateReason reason)335 WMError WindowNodeContainer::UpdateWindowNode(sptr<WindowNode>& node, WindowUpdateReason reason)
336 {
337 // Get last displayId and last showing displays before layout
338 auto lastShowingDisplays = node->GetShowingDisplays();
339
340 // PreProcess window node and layout node
341 displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
342 if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) {
343 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId());
344 }
345 layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE);
346 displayGroupController_->PostProcessWindowNode(node);
347 // Get current displayId and showing displays, update RSTree and displayGroupWindowTree
348 UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays);
349 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_UPDATE);
350 WLOGD("UpdateNode Id: %{public}u end", node->GetWindowId());
351 return WMError::WM_OK;
352 }
353
RemoveWindowNodeFromWindowTree(sptr<WindowNode> & node)354 void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr<WindowNode>& node)
355 {
356 // remove this node from parent
357 auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node);
358 if (iter != node->parent_->children_.end()) {
359 node->parent_->children_.erase(iter);
360 } else {
361 WLOGFE("can't find this node in parent");
362 }
363 node->parent_ = nullptr;
364 }
365
RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)366 void WindowNodeContainer::RemoveFromRsTreeWhenRemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
367 {
368 if (fromAnimation || (RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) &&
369 node->stateMachine_.IsHideAnimationPlaying())) {
370 WLOGFD("not remove from rs tree id:%{public}u", node->GetWindowId());
371 return;
372 }
373 // When RemoteAnimation exists, remove node from rs tree after animation
374 WLOGFD("Id:%{public}u, isPlayAnimationHide_:%{public}u", node->GetWindowId(),
375 static_cast<uint32_t>(node->isPlayAnimationHide_));
376 // subwindow or no remote animation also exit with animation
377 for (auto& displayId : node->GetShowingDisplays()) {
378 RemoveNodeFromRSTree(node, displayId, displayId, WindowUpdateType::WINDOW_UPDATE_REMOVED,
379 node->isPlayAnimationHide_);
380 }
381 }
382
SetSurfaceNodeVisible(sptr<WindowNode> & node,int32_t topPriority,bool visible)383 void WindowNodeContainer::SetSurfaceNodeVisible(sptr<WindowNode>& node, int32_t topPriority, bool visible)
384 {
385 if (node == nullptr) {
386 return;
387 }
388 if (node->parent_ != nullptr && node->currentVisibility_) {
389 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
390 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
391 auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
392 if (surfaceNode) {
393 surfaceNode->SetVisible(visible);
394 }
395 }
396 }
397 for (auto& childNode : node->children_) {
398 SetSurfaceNodeVisible(childNode, topPriority, visible);
399 }
400 }
401
SetBelowScreenlockVisible(sptr<WindowNode> & node,bool visible)402 void WindowNodeContainer::SetBelowScreenlockVisible(sptr<WindowNode>& node, bool visible)
403 {
404 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
405 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
406 for (auto& node : rootNodes) {
407 SetSurfaceNodeVisible(node, topPriority, visible);
408 }
409 }
410
RemoveWindowNode(sptr<WindowNode> & node,bool fromAnimation)411 WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node, bool fromAnimation)
412 {
413 if (node == nullptr) {
414 WLOGFE("window node or surface node is nullptr, invalid");
415 return WMError::WM_ERROR_DESTROYED_OBJECT;
416 }
417 if (node->parent_ == nullptr) {
418 WLOGFW("can't find parent of this node");
419 } else {
420 RemoveWindowNodeFromWindowTree(node);
421 }
422
423 node->requestedVisibility_ = false;
424 node->currentVisibility_ = false;
425 RemoveFromRsTreeWhenRemoveWindowNode(node, fromAnimation);
426 node->isPlayAnimationHide_ = false;
427 displayGroupController_->UpdateDisplayGroupWindowTree();
428 layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_REMOVED);
429 WindowMode lastMode = node->GetWindowMode();
430 if (HandleRemoveWindow(node) != WMError::WM_OK) {
431 return WMError::WM_ERROR_NULLPTR;
432 }
433 if (!WindowHelper::IsFloatingWindow(lastMode)) {
434 NotifyDockWindowStateChanged(node, true);
435 }
436 NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_REMOVE);
437 DumpScreenWindowTreeByWinId(node->GetWindowId());
438 UpdateCameraFloatWindowStatus(node, false);
439 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
440 isScreenLocked_ = false;
441 SetBelowScreenlockVisible(node, true);
442 }
443 WLOGI("Remove Id: %{public}u end", node->GetWindowId());
444 RSInterfaces::GetInstance().SetAppWindowNum(GetAppWindowNum());
445
446 // update private window count and notify dms private status changed
447 if (node->GetWindowProperty()->GetPrivacyMode()) {
448 UpdatePrivateStateAndNotify();
449 }
450 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
451 WindowInfoReporter::GetInstance().InsertHideReportInfo(node->abilityInfo_.bundleName_);
452 }
453 HandleRemoveWindowDisplayOrientation(node, fromAnimation);
454 return WMError::WM_OK;
455 }
456
HandleRemoveWindowDisplayOrientation(sptr<WindowNode> & node,bool fromAnimation)457 void WindowNodeContainer::HandleRemoveWindowDisplayOrientation(sptr<WindowNode>& node, bool fromAnimation)
458 {
459 if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
460 WLOGFD("[FixOrientation] not full screen window remove, do not update orientation");
461 return;
462 }
463 if (!FIX_ORIENTATION_ENABLE) {
464 auto nextRotatableWindow = GetNextRotatableWindow(node->GetWindowId());
465 if (nextRotatableWindow != nullptr) {
466 SetDisplayOrientationFromWindow(nextRotatableWindow, true);
467 }
468 return;
469 }
470 if (!fromAnimation) {
471 if (node->stateMachine_.IsHideAnimationPlaying()) {
472 WLOGFD("[FixOrientation] removing window is playing hide animation, do not update display orientation");
473 return;
474 }
475 auto nextRotatableWindow = GetNextRotatableWindow(node->GetWindowId());
476 if (nextRotatableWindow == nullptr) {
477 WLOGFD("[FixOrientation] no next window, do not update display orientation");
478 return;
479 }
480 WLOGFD("[FixOrientation] nexi rotatable window: %{public}u", nextRotatableWindow->GetWindowId());
481 if (nextRotatableWindow->stateMachine_.IsShowAnimationPlaying()) {
482 WLOGFD("[FixOrientation] next window is playing show animation, do not update display orientation");
483 return;
484 }
485 if (WmsUtils::IsFixedOrientation(nextRotatableWindow->GetRequestedOrientation(),
486 nextRotatableWindow->GetWindowMode(), nextRotatableWindow->GetWindowFlags())) {
487 WLOGFI("[FixOrientation] next rotatable window is fixed, do not animation");
488 SetDisplayOrientationFromWindow(nextRotatableWindow, false);
489 } else {
490 SetDisplayOrientationFromWindow(nextRotatableWindow, true);
491 }
492 }
493 }
494
SetDisplayOrientationFromWindow(sptr<WindowNode> & node,bool withAnimation)495 void WindowNodeContainer::SetDisplayOrientationFromWindow(sptr<WindowNode>& node, bool withAnimation)
496 {
497 DisplayManagerServiceInner::GetInstance().SetOrientationFromWindow(node->GetDisplayId(),
498 node->GetRequestedOrientation(), withAnimation);
499 }
500
UpdatePrivateStateAndNotify()501 void WindowNodeContainer::UpdatePrivateStateAndNotify()
502 {
503 uint32_t prePrivateWindowCount = privateWindowCount_;
504 WLOGFD("before update : privateWindow count: %{public}u", prePrivateWindowCount);
505 UpdatePrivateWindowCount();
506 if (prePrivateWindowCount == 0 && privateWindowCount_ == 1) {
507 DisplayManagerServiceInner::GetInstance().NotifyPrivateWindowStateChanged(true);
508 } else if (prePrivateWindowCount == 1 && privateWindowCount_ == 0) {
509 DisplayManagerServiceInner::GetInstance().NotifyPrivateWindowStateChanged(false);
510 }
511 }
512
UpdatePrivateWindowCount()513 void WindowNodeContainer::UpdatePrivateWindowCount()
514 {
515 std::vector<sptr<WindowNode>> windowNodes;
516 TraverseContainer(windowNodes);
517 uint32_t count = 0;
518 for (const auto& node : windowNodes) {
519 if (node->GetWindowProperty()->GetPrivacyMode()) {
520 ++count;
521 }
522 }
523 privateWindowCount_ = count;
524 WLOGFD("after update : privateWindow count: %{public}u", privateWindowCount_);
525 }
526
GetAppWindowNum()527 uint32_t WindowNodeContainer::GetAppWindowNum()
528 {
529 uint32_t num = 0;
530 for (auto& child : appWindowNode_->children_) {
531 if (WindowHelper::IsAppWindow(child->GetWindowType())) {
532 num++;
533 }
534 }
535 return num;
536 }
537
SetConfigMainFloatingWindowAbove(bool isAbove)538 void WindowNodeContainer::SetConfigMainFloatingWindowAbove(bool isAbove)
539 {
540 isFloatWindowAboveFullWindow_ = isAbove;
541 }
542
SetMaxMainFloatingWindowNumber(uint32_t maxNumber)543 void WindowNodeContainer::SetMaxMainFloatingWindowNumber(uint32_t maxNumber)
544 {
545 maxMainFloatingWindowNumber_ = maxNumber;
546 }
547
ResetMainFloatingWindowPriorityIfNeeded(sptr<WindowNode> & windowNode)548 void WindowNodeContainer::ResetMainFloatingWindowPriorityIfNeeded(sptr<WindowNode>& windowNode)
549 {
550 if (!isFloatWindowAboveFullWindow_) {
551 return;
552 }
553 const WindowType& windowType = windowNode->GetWindowType();
554 const WindowMode& windowMode = windowNode->GetWindowMode();
555 if (!WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
556 return;
557 }
558 const int32_t priorityOffset = 1;
559 auto baseZOrderPolicy = zorderPolicy_->GetWindowPriority(windowType);
560 if (isScreenLocked_ &&
561 (windowNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
562 // if window show when lock, priority should bigger than KEYGUARD.
563 baseZOrderPolicy = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
564 }
565
566 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(windowNode->GetDisplayId());
567 if (windowPair != nullptr && windowPair->IsDuringSplit()) {
568 windowNode->priority_ = baseZOrderPolicy - priorityOffset;
569 WLOGFD("Reset floating main window zorder priority.[windowId: %{public}u, priority: %{public}d] ",
570 windowNode->GetWindowId(), windowNode->priority_);
571 return;
572 }
573
574 windowNode->priority_ = baseZOrderPolicy + priorityOffset;
575 WLOGFD("Reset floating main window zorder priority.[windowId: %{public}u, priority: %{public}d] ",
576 windowNode->GetWindowId(), windowNode->priority_);
577 }
578
ResetAllMainFloatingWindowZOrder(sptr<WindowNode> & rootNode)579 void WindowNodeContainer::ResetAllMainFloatingWindowZOrder(sptr<WindowNode>& rootNode)
580 {
581 if (!isFloatWindowAboveFullWindow_) {
582 WLOGFD("The free window level above full screen window feature is turned off");
583 return;
584 }
585 if (rootNode != appWindowNode_ && rootNode != aboveAppWindowNode_) {
586 return;
587 }
588 /*
589 * update all mainFloatingWindow position on window tree with
590 * the same raleative position between mainFloatingWindows.
591 */
592 std::vector<sptr<WindowNode>> tempWindows;
593 auto itor = rootNode->children_.begin();
594 while (itor != rootNode->children_.end()) {
595 const WindowType& windowType = (*itor)->GetWindowType();
596 const WindowMode& windowMode = (*itor)->GetWindowMode();
597 if (WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
598 tempWindows.push_back(*itor);
599 itor = rootNode->children_.erase(itor);
600 } else {
601 itor++;
602 }
603 }
604
605 for (auto& node : tempWindows) {
606 UpdateWindowTree(node);
607 }
608 }
609
HandleRemoveWindow(sptr<WindowNode> & node)610 WMError WindowNodeContainer::HandleRemoveWindow(sptr<WindowNode>& node)
611 {
612 WLOGFD("start");
613 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
614 if (windowPair == nullptr) {
615 WLOGFE("Window pair is nullptr");
616 return WMError::WM_ERROR_NULLPTR;
617 }
618 windowPair->HandleRemoveWindow(node);
619 auto dividerWindow = windowPair->GetDividerWindow();
620 auto type = node->GetWindowType();
621 if ((type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) &&
622 dividerWindow != nullptr) {
623 UpdateWindowNode(dividerWindow, WindowUpdateReason::UPDATE_RECT);
624 }
625 WLOGFD("end");
626 return WMError::WM_OK;
627 }
628
DestroyWindowNode(sptr<WindowNode> & node,std::vector<uint32_t> & windowIds)629 WMError WindowNodeContainer::DestroyWindowNode(sptr<WindowNode>& node, std::vector<uint32_t>& windowIds)
630 {
631 WMError ret = RemoveWindowNode(node);
632 if (ret != WMError::WM_OK) {
633 WLOGFE("RemoveWindowNode failed");
634 return ret;
635 }
636 StartingWindow::ReleaseStartWinSurfaceNode(node);
637 node->surfaceNode_ = nullptr;
638 windowIds.push_back(node->GetWindowId());
639 for (auto& child : node->children_) { // destroy sub window if exists
640 windowIds.push_back(child->GetWindowId());
641 child->parent_ = nullptr;
642 if (child->surfaceNode_ != nullptr) {
643 WLOGI("child surfaceNode set nullptr");
644 child->surfaceNode_ = nullptr;
645 }
646 }
647
648 // clear vector cache completely, swap with empty vector
649 auto emptyVector = std::vector<sptr<WindowNode>>();
650 node->children_.swap(emptyVector);
651 if (node->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) {
652 RemoteAnimation::NotifyAnimationUpdateWallpaper(nullptr);
653 }
654 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
655 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(node->abilityInfo_.bundleName_);
656 }
657
658 UpdateAvoidAreaListener(node, false);
659 WLOGI("DestroyNode Id: %{public}u end", node->GetWindowId());
660 return WMError::WM_OK;
661 }
662
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowSizeChangeReason reason)663 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowSizeChangeReason reason)
664 {
665 if (!node->GetWindowToken()) {
666 WLOGFE("windowToken is null");
667 return;
668 }
669 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
670 for (auto& child : appWindowNode_->children_) {
671 if (child->IsSplitMode() && child->GetWindowToken()) {
672 layoutPolicy_->NotifyClientAndAnimation(child, child->GetWindowRect(), reason);
673 WLOGI("Notify split window that drag is start or end, Id: "
674 "%{public}d, reason: %{public}u", child->GetWindowId(), reason);
675 }
676 }
677 } else {
678 layoutPolicy_->NotifyClientAndAnimation(node, node->GetWindowRect(), reason);
679 WLOGI("Notify window that drag is start or end, windowId: %{public}d, "
680 "reason: %{public}u", node->GetWindowId(), reason);
681 }
682 }
683
UpdateWindowTree(sptr<WindowNode> & node)684 void WindowNodeContainer::UpdateWindowTree(sptr<WindowNode>& node)
685 {
686 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
687 node->priority_ = zorderPolicy_->GetWindowPriority(node->GetWindowType());
688 RaiseInputMethodWindowPriorityIfNeeded(node);
689 RaiseShowWhenLockedWindowIfNeeded(node);
690 ResetMainFloatingWindowPriorityIfNeeded(node);
691 auto parentNode = node->parent_;
692 if (parentNode == nullptr) {
693 WLOGI("Current window node has no parent: %{public}u", node->GetWindowId());
694 return;
695 }
696 auto iter = std::find(parentNode->children_.begin(), parentNode->children_.end(), node);
697 if (iter != parentNode->children_.end()) {
698 WLOGI("node %{public}u already on window tree, not update!", node->GetWindowId());
699 return;
700 }
701 auto position = parentNode->children_.end();
702 int splitWindowCnt = 0;
703 for (auto child = parentNode->children_.begin(); child < parentNode->children_.end(); ++child) {
704 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && splitWindowCnt == SPLIT_WINDOWS_CNT) {
705 position = child;
706 break;
707 }
708 if (WindowHelper::IsSplitWindowMode((*child)->GetWindowMode())) {
709 splitWindowCnt++;
710 }
711 if ((*child)->priority_ > node->priority_) {
712 position = child;
713 break;
714 }
715 }
716 parentNode->children_.insert(position, node);
717 }
718
AddAppSurfaceNodeOnRSTree(sptr<WindowNode> & node)719 bool WindowNodeContainer::AddAppSurfaceNodeOnRSTree(sptr<WindowNode>& node)
720 {
721 /*
722 * App main window must has starting window, and show after starting window
723 * Starting Window has already update leashWindowSurfaceNode and starting window surfaceNode on RSTree
724 * Just need add appSurface Node as child of leashWindowSurfaceNode
725 */
726 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AddAppSurfaceNodeOnRSTree(%u)", node->GetWindowId());
727 if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
728 WLOGFE("id:%{public}u not main app window but has start window", node->GetWindowId());
729 return false;
730 }
731 if (!node->leashWinSurfaceNode_ || !node->surfaceNode_) {
732 WLOGFE("id:%{public}u leashWinSurfaceNode or surfaceNode is null but has start window!", node->GetWindowId());
733 return false;
734 }
735 WLOGI("AddAppSurfaceNodeOnRSTree Id: %{public}d", node->GetWindowId());
736 if (!node->currentVisibility_) {
737 WLOGI("id: %{public}d is invisible, no need update RS tree", node->GetWindowId());
738 return false;
739 }
740 node->leashWinSurfaceNode_->AddChild(node->surfaceNode_, -1);
741 return true;
742 }
743
OpenInputMethodSyncTransaction()744 void WindowNodeContainer::OpenInputMethodSyncTransaction()
745 {
746 if (!isAnimateTransactionEnabled_) {
747 WLOGD("InputMethodSyncTransaction is not enabled");
748 return;
749 }
750 // Before open transaction, it must flush first.
751 auto transactionProxy = RSTransactionProxy::GetInstance();
752 if (!transactionProxy) {
753 return;
754 }
755 transactionProxy->FlushImplicitTransaction();
756 auto syncTransactionController = RSSyncTransactionController::GetInstance();
757 if (syncTransactionController) {
758 syncTransactionController->OpenSyncTransaction();
759 }
760 WLOGD("OpenInputMethodSyncTransaction");
761 }
762
CloseInputMethodSyncTransaction()763 void WindowNodeContainer::CloseInputMethodSyncTransaction()
764 {
765 if (!isAnimateTransactionEnabled_) {
766 WLOGD("InputMethodSyncTransaction is not enabled while close");
767 return;
768 }
769 auto syncTransactionController = RSSyncTransactionController::GetInstance();
770 if (syncTransactionController) {
771 syncTransactionController->CloseSyncTransaction();
772 }
773 WLOGD("CloseInputMethodSyncTransaction");
774 }
775
IsWindowFollowParent(WindowType type)776 bool WindowNodeContainer::IsWindowFollowParent(WindowType type)
777 {
778 auto isPhone = uiType_ == UI_TYPE_PHONE;
779 if (!isPhone) {
780 return false;
781 }
782 return WindowHelper::IsWindowFollowParent(type);
783 }
784
AddNodeOnRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)785 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
786 WindowUpdateType type, bool animationPlayed)
787 {
788 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
789 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
790 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
791 WLOGI("no need to update RSTree");
792 return true;
793 }
794 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
795 WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
796 "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
797 node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
798 auto updateRSTreeFunc = [&]() {
799 if (!node->currentVisibility_) {
800 WLOGI("id: %{public}d invisible, no need update RS tree", node->GetWindowId());
801 return;
802 }
803
804 if (IsWindowFollowParent(node->GetWindowType())) {
805 auto& parentNode = node->parent_;
806 if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
807 node->surfaceNode_ != nullptr) {
808 node->surfaceNode_->SetTranslateX(node->GetWindowRect().posX_ - parentNode->GetWindowRect().posX_);
809 node->surfaceNode_->SetTranslateY(node->GetWindowRect().posY_ - parentNode->GetWindowRect().posY_);
810 node->surfaceNode_->SetVisible(true);
811 parentNode->surfaceNode_->AddChild(node->surfaceNode_, -1);
812 WLOGFD("Add surfaceNode to parent surfaceNode succeed.");
813 return;
814 }
815 }
816 auto& dms = DisplayManagerServiceInner::GetInstance();
817 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
818 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
819 for (auto& child : node->children_) {
820 if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
821 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
822 }
823 }
824 };
825
826 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
827 updateRSTreeFunc();
828 return true;
829 }
830
831 WindowGravity windowGravity;
832 uint32_t percent;
833 node->GetWindowGravity(windowGravity, percent);
834 if (node->EnableDefaultAnimation(animationPlayed)) {
835 WLOGFD("Add node with animation");
836 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
837 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
838 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
839 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
840 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
841 windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT &&
842 !animationPlayed) { // add keyboard with animation
843 auto timingProtocol = animationConfig_.keyboardAnimationIn_.duration_;
844 OpenInputMethodSyncTransaction();
845 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationIn_.curve_, updateRSTreeFunc);
846 CloseInputMethodSyncTransaction();
847 } else {
848 WLOGFD("add node without animation");
849 updateRSTreeFunc();
850 }
851 return true;
852 }
853
RemoveNodeFromRSTree(sptr<WindowNode> & node,DisplayId displayId,DisplayId parentDisplayId,WindowUpdateType type,bool animationPlayed)854 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
855 WindowUpdateType type, bool animationPlayed)
856 {
857 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
858 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
859 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
860 WLOGI("no need to update RSTree");
861 return true;
862 }
863 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
864 WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
865 "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
866 node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
867 auto updateRSTreeFunc = [&]() {
868 if (IsWindowFollowParent(node->GetWindowType())) {
869 const auto& parentNode = node->parent_;
870 if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
871 node->surfaceNode_ != nullptr) {
872 node->surfaceNode_->SetVisible(false);
873 parentNode->surfaceNode_->RemoveChild(node->surfaceNode_);
874 WLOGFD("Remove surfaceNode to parent surfaceNode succeed.");
875 return;
876 }
877 }
878 auto& dms = DisplayManagerServiceInner::GetInstance();
879 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
880 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
881 for (auto& child : node->children_) {
882 if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
883 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
884 }
885 }
886 };
887
888 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
889 updateRSTreeFunc();
890 return true;
891 }
892
893 WindowGravity windowGravity;
894 uint32_t percent;
895 node->GetWindowGravity(windowGravity, percent);
896 if (node->EnableDefaultAnimation(animationPlayed)) {
897 WLOGFD("remove with animation");
898 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
899 if (node->surfaceNode_) {
900 node->surfaceNode_->SetFreeze(true);
901 }
902 wptr<WindowNode> weakNode(node);
903 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
904 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
905 auto weakWindow = weakNode.promote();
906 if (weakWindow && weakWindow->surfaceNode_) {
907 weakWindow->surfaceNode_->SetFreeze(false);
908 }
909 });
910 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
911 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
912 windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT && !animationPlayed) {
913 // remove keyboard with animation
914 OpenInputMethodSyncTransaction();
915 auto timingProtocol = animationConfig_.keyboardAnimationOut_.duration_;
916 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationOut_.curve_, updateRSTreeFunc);
917 CloseInputMethodSyncTransaction();
918 } else {
919 updateRSTreeFunc();
920 }
921 return true;
922 }
923
Destroy()924 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
925 {
926 // clear vector cache completely, swap with empty vector
927 auto emptyVector = std::vector<uint32_t>();
928 removedIds_.swap(emptyVector);
929 for (auto& node : belowAppWindowNode_->children_) {
930 DestroyWindowNode(node, removedIds_);
931 }
932 for (auto& node : appWindowNode_->children_) {
933 DestroyWindowNode(node, removedIds_);
934 }
935 for (auto& node : aboveAppWindowNode_->children_) {
936 DestroyWindowNode(node, removedIds_);
937 }
938 return removedIds_;
939 }
940
FindRoot(WindowType type) const941 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
942 {
943 if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
944 type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
945 type == WindowType::WINDOW_TYPE_DIALOG) {
946 return appWindowNode_;
947 }
948 if (WindowHelper::IsBelowSystemWindow(type)) {
949 return belowAppWindowNode_;
950 }
951 if (WindowHelper::IsAboveSystemWindow(type)) {
952 return aboveAppWindowNode_;
953 }
954 return nullptr;
955 }
956
FindWindowNodeById(uint32_t id) const957 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
958 {
959 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
960 for (const auto& rootNode : rootNodes) {
961 for (auto& node : rootNode->children_) {
962 if (node->GetWindowId() == id) {
963 return node;
964 }
965 for (auto& subNode : node->children_) {
966 if (subNode->GetWindowId() == id) {
967 return subNode;
968 }
969 }
970 }
971 }
972 return nullptr;
973 }
974
UpdateFocusStatus(uint32_t id,bool focused)975 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
976 {
977 auto node = FindWindowNodeById(id);
978 if (node == nullptr) {
979 WLOGFW("cannot find focused window id:%{public}d", id);
980 return;
981 }
982 if (focused) {
983 focusedPid_ = node->GetCallingPid();
984 }
985 node->isFocused_ = focused;
986 // change focus window shadow
987 WindowSystemEffect::SetWindowShadow(node);
988 if (node->GetCallingPid() == 0) {
989 WLOGFW("focused window is starting window, no need notify");
990 return;
991 }
992
993 if (focused && node->GetWindowProperty() != nullptr) {
994 AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
995 WLOGFD("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
996 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
997 node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
998 node->GetCallingPid(), node->GetCallingUid());
999 uint64_t focusNodeId = 0; // 0 means invalid
1000 if (node->surfaceNode_ == nullptr) {
1001 WLOGFW("focused window surfaceNode is null");
1002 } else {
1003 focusNodeId = node->surfaceNode_->GetId();
1004 }
1005 FocusAppInfo appInfo =
1006 { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_, focusNodeId };
1007 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
1008 }
1009 if (node->GetWindowToken()) {
1010 node->GetWindowToken()->UpdateFocusStatus(focused);
1011 }
1012 if (node->abilityToken_ == nullptr) {
1013 WLOGW("AbilityToken is null, window : %{public}d", id);
1014 }
1015 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
1016 node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
1017 WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
1018 focusChangeInfo, focused);
1019 }
1020
UpdateActiveStatus(uint32_t id,bool isActive)1021 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
1022 {
1023 auto node = FindWindowNodeById(id);
1024 if (node == nullptr) {
1025 WLOGFE("cannot find active window id: %{public}d", id);
1026 return;
1027 }
1028 if (isActive) {
1029 activePid_ = node->GetCallingPid();
1030 }
1031 if (node->GetWindowToken()) {
1032 node->GetWindowToken()->UpdateActiveStatus(isActive);
1033 }
1034 }
1035
UpdateBrightness(uint32_t id,bool byRemoved)1036 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
1037 {
1038 auto node = FindWindowNodeById(id);
1039 if (node == nullptr) {
1040 WLOGFE("cannot find active window id: %{public}d", id);
1041 return;
1042 }
1043
1044 if (!byRemoved) {
1045 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
1046 return;
1047 }
1048 }
1049 WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
1050 if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
1051 if (GetDisplayBrightness() != node->GetBrightness()) {
1052 WLOGI("adjust brightness with default value");
1053 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1054 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
1055 #endif
1056 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
1057 }
1058 SetBrightnessWindow(INVALID_WINDOW_ID);
1059 } else {
1060 if (GetDisplayBrightness() != node->GetBrightness()) {
1061 WLOGI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
1062 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1063 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
1064 ToOverrideBrightness(node->GetBrightness()));
1065 #endif
1066 SetDisplayBrightness(node->GetBrightness());
1067 }
1068 SetBrightnessWindow(node->GetWindowId());
1069 }
1070 }
1071
AssignZOrder()1072 void WindowNodeContainer::AssignZOrder()
1073 {
1074 zOrder_ = 0;
1075 WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
1076 if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
1077 ++zOrder_;
1078 WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
1079 return false;
1080 }
1081 if (node->leashWinSurfaceNode_ != nullptr) {
1082 ++zOrder_;
1083 node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
1084 }
1085
1086 if (node->surfaceNode_ != nullptr) {
1087 ++zOrder_;
1088 node->surfaceNode_->SetPositionZ(zOrder_);
1089 node->zOrder_ = zOrder_;
1090 }
1091 // make sure starting window above app
1092 if (node->startingWinSurfaceNode_ != nullptr) {
1093 ++zOrder_;
1094 node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
1095 }
1096 return false;
1097 };
1098 TraverseWindowTree(func, false);
1099 displayGroupController_->UpdateDisplayGroupWindowTree();
1100 }
1101
SetFocusWindow(uint32_t windowId)1102 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
1103 {
1104 if (focusedWindow_ == windowId) {
1105 WLOGI("Focus window not change, id: %{public}u, %{public}d", windowId, focusedPid_);
1106 // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
1107 // This info is invalid, so we must notify again when first frame callback.
1108 if (focusedPid_ == 0) {
1109 UpdateFocusStatus(windowId, true);
1110 }
1111 return WMError::WM_DO_NOTHING;
1112 }
1113 UpdateFocusStatus(focusedWindow_, false);
1114 focusedWindow_ = windowId;
1115 UpdateFocusStatus(focusedWindow_, true);
1116 return WMError::WM_OK;
1117 }
1118
GetFocusWindow() const1119 uint32_t WindowNodeContainer::GetFocusWindow() const
1120 {
1121 return focusedWindow_;
1122 }
1123
SetActiveWindow(uint32_t windowId,bool byRemoved)1124 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
1125 {
1126 if (activeWindow_ == windowId) {
1127 WLOGI("Active window not change, id: %{public}u, %{public}d", windowId, activePid_);
1128 if (activePid_ == 0) {
1129 UpdateActiveStatus(windowId, true);
1130 }
1131 return WMError::WM_DO_NOTHING;
1132 }
1133 UpdateActiveStatus(activeWindow_, false);
1134 activeWindow_ = windowId;
1135 UpdateActiveStatus(activeWindow_, true);
1136 UpdateBrightness(activeWindow_, byRemoved);
1137 return WMError::WM_OK;
1138 }
1139
SetDisplayBrightness(float brightness)1140 void WindowNodeContainer::SetDisplayBrightness(float brightness)
1141 {
1142 displayBrightness_ = brightness;
1143 }
1144
GetDisplayBrightness() const1145 float WindowNodeContainer::GetDisplayBrightness() const
1146 {
1147 return displayBrightness_;
1148 }
1149
SetBrightnessWindow(uint32_t windowId)1150 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
1151 {
1152 brightnessWindow_ = windowId;
1153 }
1154
GetBrightnessWindow() const1155 uint32_t WindowNodeContainer::GetBrightnessWindow() const
1156 {
1157 return brightnessWindow_;
1158 }
1159
ToOverrideBrightness(float brightness)1160 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
1161 {
1162 return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
1163 }
1164
GetActiveWindow() const1165 uint32_t WindowNodeContainer::GetActiveWindow() const
1166 {
1167 return activeWindow_;
1168 }
1169
GetLayoutPolicy() const1170 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
1171 {
1172 return layoutPolicy_;
1173 }
1174
GetAvoidController() const1175 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
1176 {
1177 return avoidController_;
1178 }
1179
GetDisplayGroupController() const1180 sptr<DisplayGroupController> WindowNodeContainer::GetDisplayGroupController() const
1181 {
1182 return displayGroupController_;
1183 }
1184
GetRootNode(WindowRootNodeType type) const1185 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
1186 {
1187 if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
1188 return aboveAppWindowNode_;
1189 } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
1190 return appWindowNode_;
1191 } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
1192 return belowAppWindowNode_;
1193 }
1194 return nullptr;
1195 }
1196
HandleKeepScreenOn(const sptr<WindowNode> & node,bool requireLock)1197 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
1198 {
1199 #ifdef POWER_MANAGER_ENABLE
1200 if (requireLock && node->keepScreenLock_ == nullptr) {
1201 // reset ipc identity
1202 std::string identity = IPCSkeleton::ResetCallingIdentity();
1203 node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
1204 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
1205 // set ipc identity to raw
1206 IPCSkeleton::SetCallingIdentity(identity);
1207 }
1208 if (node->keepScreenLock_ == nullptr) {
1209 return;
1210 }
1211 WLOGI("keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
1212 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
1213 node->GetWindowName().c_str(), requireLock);
1214 ErrCode res;
1215 // reset ipc identity
1216 std::string identity = IPCSkeleton::ResetCallingIdentity();
1217 if (requireLock) {
1218 res = node->keepScreenLock_->Lock();
1219 } else {
1220 res = node->keepScreenLock_->UnLock();
1221 }
1222 // set ipc identity to raw
1223 IPCSkeleton::SetCallingIdentity(identity);
1224 if (res != ERR_OK) {
1225 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
1226 }
1227 #endif
1228 }
1229
IsAboveSystemBarNode(sptr<WindowNode> node) const1230 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
1231 {
1232 int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
1233 if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
1234 (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
1235 return true;
1236 }
1237 return false;
1238 }
1239
IsSplitImmersiveNode(sptr<WindowNode> node) const1240 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
1241 {
1242 auto type = node->GetWindowType();
1243 return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
1244 }
1245
GetExpectImmersiveProperty(DisplayId id,sptr<WindowNode> & triggerWindow) const1246 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty(DisplayId id,
1247 sptr<WindowNode>& triggerWindow) const
1248 {
1249 std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
1250 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty() },
1251 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
1252 };
1253
1254 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
1255 if (layoutMode_ == WindowLayoutMode::TILE) {
1256 rootNodes = { aboveAppWindowNode_, belowAppWindowNode_ };
1257 }
1258
1259 for (const auto& node : rootNodes) {
1260 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
1261 auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1262 if (IsAboveSystemBarNode(*iter)) {
1263 continue;
1264 }
1265 if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1266 && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1267 auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(id);
1268 if (displayInfo && WmsUtils::IsExpectedRotateLandscapeWindow((*iter)->GetRequestedOrientation(),
1269 displayInfo->GetDisplayOrientation(), (*iter)->GetWindowFlags())) {
1270 WLOGFI("Horizontal window id: %{public}d make it immersive", (*iter)->GetWindowId());
1271 for (auto it : sysBarPropMap) {
1272 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1273 sysBarPropMap[it.first].enable_ = false;
1274 }
1275 } else {
1276 WLOGFD("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1277 for (auto it : sysBarPropMap) {
1278 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1279 }
1280 triggerWindow = (*iter);
1281 }
1282 return sysBarPropMap;
1283 } else if (IsSplitImmersiveNode(*iter)) {
1284 WLOGFD("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1285 for (auto it : sysBarPropMap) {
1286 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1287 sysBarPropMap[it.first].enable_ = false;
1288 }
1289 return sysBarPropMap;
1290 }
1291 }
1292 }
1293
1294 WLOGFD("No immersive window on top. Use default systembar Property");
1295 return sysBarPropMap;
1296 }
1297
NotifyIfAvoidAreaChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1298 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1299 const AvoidControlType avoidType) const
1300 {
1301 auto checkFunc = [this](sptr<WindowNode> node) {
1302 return CheckWindowNodeWhetherInWindowTree(node);
1303 };
1304 avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1305 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1306 NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1307 } else {
1308 NotifyIfSystemBarTintChanged(node->GetDisplayId());
1309 }
1310
1311 NotifyIfKeyboardRegionChanged(node, avoidType);
1312 }
1313
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1314 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1315 {
1316 avoidController_->SetFlagForProcessWindowChange(true);
1317 }
1318
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1319 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1320 {
1321 avoidController_->SetFlagForProcessWindowChange(false);
1322 auto checkFunc = [this](sptr<WindowNode> node) {
1323 return CheckWindowNodeWhetherInWindowTree(node);
1324 };
1325 WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1326 avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1327 return false;
1328 };
1329 TraverseWindowTree(func, true);
1330 }
1331
NotifyIfSystemBarTintChanged(DisplayId displayId) const1332 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1333 {
1334 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1335 sptr<WindowNode> triggerWindow = nullptr;
1336 auto expectSystemBarProp = GetExpectImmersiveProperty(displayId, triggerWindow);
1337 JudgeToReportSystemBarInfo(triggerWindow, expectSystemBarProp);
1338 SystemBarRegionTints tints;
1339 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1340 for (auto it : sysBarTintMap) {
1341 auto expectProp = expectSystemBarProp.find(it.first)->second;
1342 if (it.second.prop_ == expectProp) {
1343 continue;
1344 }
1345 WLOGFD("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1346 static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1347 sysBarTintMap[it.first].prop_ = expectProp;
1348 sysBarTintMap[it.first].type_ = it.first;
1349 tints.emplace_back(sysBarTintMap[it.first]);
1350 }
1351 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1352 }
1353
JudgeToReportSystemBarInfo(const sptr<WindowNode> window,const std::unordered_map<WindowType,SystemBarProperty> & systemBarPropInfo) const1354 void WindowNodeContainer::JudgeToReportSystemBarInfo(const sptr<WindowNode> window,
1355 const std::unordered_map<WindowType, SystemBarProperty>& systemBarPropInfo) const
1356 {
1357 if (window == nullptr || !WindowHelper::IsMainWindow(window->GetWindowType())) {
1358 WLOGFD("No need to report");
1359 return;
1360 }
1361
1362 // 2 means the must size of systemBarPropInfo.
1363 if (systemBarPropInfo.size() != 2) {
1364 return;
1365 }
1366
1367 auto bundleName = window->abilityInfo_.bundleName_;
1368 auto abilityName = window->abilityInfo_.abilityName_;
1369 auto navigationItor = systemBarPropInfo.find(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
1370 if (navigationItor != systemBarPropInfo.end() && !navigationItor->second.enable_) {
1371 WindowInfoReporter::GetInstance().InsertNavigationBarReportInfo(bundleName, abilityName);
1372 WLOGFD("the navigation bar is disabled by window. windowId:[%{public}u]", window->GetWindowId());
1373 }
1374 }
1375
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1376 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1377 {
1378 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1379 SystemBarRegionTints tints;
1380 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1381 SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1382 for (auto it : sysBarTintMap) { // split screen mode not support yet
1383 auto sysNode = sysBarNodeMap[it.first];
1384 if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1385 continue;
1386 }
1387 const Rect& newRegion = sysNode->GetWindowRect();
1388 sysBarTintMap[it.first].region_ = newRegion;
1389 sysBarTintMap[it.first].type_ = it.first;
1390 tints.emplace_back(sysBarTintMap[it.first]);
1391 WLOGD("system bar region update, type: %{public}d" \
1392 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1393 static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1394 }
1395 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1396 }
1397
NotifyIfKeyboardRegionChanged(const sptr<WindowNode> & node,const AvoidControlType avoidType) const1398 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1399 const AvoidControlType avoidType) const
1400 {
1401 WindowGravity windowGravity;
1402 uint32_t percent;
1403 node->GetWindowGravity(windowGravity, percent);
1404 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
1405 windowGravity == WindowGravity::WINDOW_GRAVITY_FLOAT) {
1406 WLOGFD("windowType: %{public}u", node->GetWindowType());
1407 return;
1408 }
1409
1410 auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1411 if (callingWindow == nullptr) {
1412 WLOGD("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1413 callingWindow = FindWindowNodeById(GetFocusWindow());
1414 }
1415 if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1416 WLOGE("does not have correct callingWindow for input method window");
1417 return;
1418 }
1419 const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1420 if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1421 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1422 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1423 const Rect keyRect = node->GetWindowRect();
1424 const Rect callingRect = callingWindow->GetWindowRect();
1425 if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1426 WLOGFD("no overlap between two windows");
1427 return;
1428 }
1429 Rect overlapRect = { 0, 0, 0, 0 };
1430 if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1431 overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1432 }
1433 double textFieldPositionY = 0.0;
1434 double textFieldHeight = 0.0;
1435 if (node->GetWindowProperty() != nullptr) {
1436 textFieldPositionY = node->GetWindowProperty()->GetTextFieldPositionY();
1437 textFieldHeight = node->GetWindowProperty()->GetTextFieldHeight();
1438 }
1439 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
1440 overlapRect, textFieldPositionY, textFieldHeight);
1441 if (isAnimateTransactionEnabled_) {
1442 auto syncTransactionController = RSSyncTransactionController::GetInstance();
1443 if (syncTransactionController) {
1444 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info,
1445 syncTransactionController->GetRSTransaction());
1446 }
1447 } else {
1448 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1449 }
1450
1451 WLOGD("keyboard size change callingWindow: [%{public}s, %{public}u], "
1452 "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1453 callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1454 overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1455 return;
1456 }
1457 WLOGFE("does not have correct callingWindowMode for input method window");
1458 }
1459
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1460 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1461 {
1462 if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1463 WLOGE("[Immersive] the number of display is error");
1464 }
1465
1466 for (auto displayId : displayIdVec) {
1467 SystemBarRegionTints tints;
1468 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1469 for (auto it : sysBarTintMap) {
1470 WLOGI("[Immersive] systembar tints, T: %{public}d, " \
1471 "V: %{public}d, C: %{public}x | %{public}x, " \
1472 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1473 static_cast<int32_t>(it.first),
1474 sysBarTintMap[it.first].prop_.enable_,
1475 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1476 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1477 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1478 tints.push_back(sysBarTintMap[it.first]);
1479 }
1480 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1481 }
1482 }
1483
NotifyDockWindowStateChanged(sptr<WindowNode> & node,bool isEnable)1484 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1485 {
1486 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1487 WLOGFD("[Immersive] begin isEnable: %{public}d", isEnable);
1488 if (isEnable) {
1489 for (auto& windowNode : appWindowNode_->children_) {
1490 if (windowNode->GetWindowId() == node->GetWindowId()) {
1491 continue;
1492 }
1493 if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1494 return;
1495 }
1496 }
1497 }
1498 SystemBarProperty prop;
1499 prop.enable_ = isEnable;
1500 SystemBarRegionTint tint;
1501 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1502 tint.prop_ = prop;
1503 SystemBarRegionTints tints;
1504 tints.push_back(tint);
1505 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1506 }
1507
NotifyDockWindowStateChanged(DisplayId displayId)1508 void WindowNodeContainer::NotifyDockWindowStateChanged(DisplayId displayId)
1509 {
1510 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1511 bool isEnable = true;
1512 for (auto& windowNode : appWindowNode_->children_) {
1513 if (WindowHelper::IsSplitWindowMode(windowNode->GetWindowMode()) ||
1514 WindowHelper::IsFullScreenWindow(windowNode->GetWindowMode())) {
1515 isEnable = false;
1516 break;
1517 }
1518 }
1519 WLOGFD("[Immersive] display %{public}" PRIu64" begin isEnable: %{public}d", displayId, isEnable);
1520 SystemBarProperty prop;
1521 prop.enable_ = isEnable;
1522 SystemBarRegionTint tint;
1523 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1524 tint.prop_ = prop;
1525 SystemBarRegionTints tints;
1526 tints.push_back(tint);
1527 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1528 }
1529
UpdateAvoidAreaListener(sptr<WindowNode> & windowNode,bool haveAvoidAreaListener)1530 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1531 {
1532 avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1533 }
1534
IsTopWindow(uint32_t windowId,sptr<WindowNode> & rootNode) const1535 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1536 {
1537 if (rootNode->children_.empty()) {
1538 WLOGFE("root does not have any node");
1539 return false;
1540 }
1541 auto node = *(rootNode->children_.rbegin());
1542 if (node == nullptr) {
1543 WLOGFE("window tree does not have any node");
1544 return false;
1545 }
1546
1547 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1548 if ((*iter)->priority_ > 0) {
1549 return (*iter)->GetWindowId() == windowId;
1550 } else {
1551 break;
1552 }
1553 }
1554 return node->GetWindowId() == windowId;
1555 }
1556
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>> & orderedNodes,std::vector<sptr<WindowNode>> & windowNodes)1557 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1558 std::vector<sptr<WindowNode>>& windowNodes)
1559 {
1560 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1561 uint32_t wid = (*iter)->GetWindowId();
1562 auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1563 [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1564 if (orderedIter != orderedNodes.end()) {
1565 iter = windowNodes.erase(iter);
1566 } else {
1567 iter++;
1568 }
1569 }
1570 for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1571 UpdateWindowTree(*iter);
1572 }
1573 return;
1574 }
1575
RaiseWindowToTop(uint32_t windowId,std::vector<sptr<WindowNode>> & windowNodes)1576 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1577 {
1578 if (windowNodes.empty()) {
1579 WLOGFE("windowNodes is empty!");
1580 return;
1581 }
1582 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1583 [windowId](sptr<WindowNode> node) {
1584 return node->GetWindowId() == windowId;
1585 });
1586 // raise app node window to top
1587 if (iter != windowNodes.end()) {
1588 sptr<WindowNode> node = *iter;
1589 windowNodes.erase(iter);
1590 UpdateWindowTree(node);
1591 WLOGD("raise window to top %{public}u", node->GetWindowId());
1592 }
1593 }
1594
TraverseContainer(std::vector<sptr<WindowNode>> & windowNodes) const1595 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1596 {
1597 for (auto& node : belowAppWindowNode_->children_) {
1598 TraverseWindowNode(node, windowNodes);
1599 }
1600 for (auto& node : appWindowNode_->children_) {
1601 TraverseWindowNode(node, windowNodes);
1602 }
1603 for (auto& node : aboveAppWindowNode_->children_) {
1604 TraverseWindowNode(node, windowNodes);
1605 }
1606 std::reverse(windowNodes.begin(), windowNodes.end());
1607 }
1608
TraverseWindowNode(sptr<WindowNode> & node,std::vector<sptr<WindowNode>> & windowNodes) const1609 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1610 {
1611 if (node == nullptr) {
1612 return;
1613 }
1614 auto iter = node->children_.begin();
1615 for (; iter < node->children_.end(); ++iter) {
1616 if ((*iter)->priority_ < 0) {
1617 windowNodes.emplace_back(*iter);
1618 } else {
1619 break;
1620 }
1621 }
1622 windowNodes.emplace_back(node);
1623 for (; iter < node->children_.end(); ++iter) {
1624 windowNodes.emplace_back(*iter);
1625 }
1626 }
1627
GetAvoidAreaByType(const sptr<WindowNode> & node,AvoidAreaType avoidAreaType) const1628 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1629 {
1630 if (CheckWindowNodeWhetherInWindowTree(node)) {
1631 return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1632 }
1633 return {};
1634 }
1635
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode> & node) const1636 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1637 {
1638 bool isInWindowTree = false;
1639 WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1640 if (node->GetWindowId() == windowNode->GetWindowId()) {
1641 isInWindowTree = true;
1642 return true;
1643 }
1644 return false;
1645 };
1646 TraverseWindowTree(func, true);
1647 return isInWindowTree;
1648 }
1649
DumpScreenWindowTreeByWinId(uint32_t winid)1650 void WindowNodeContainer::DumpScreenWindowTreeByWinId(uint32_t winid)
1651 {
1652 WLOGFD("------ dump window info begin -------");
1653 WLOGFD("WindowName WinId Type Mode ZOrd [ x y w h]");
1654 uint32_t zOrder = zOrder_;
1655 WindowNodeOperationFunc func = [&zOrder, &winid](sptr<WindowNode> node) {
1656 Rect rect = node->GetWindowRect();
1657 uint32_t windowId = node->GetWindowId();
1658 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1659 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1660 if (winid == windowId) {
1661 WLOGD("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u "
1662 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1663 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1664 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1665 } else {
1666 WLOGD("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u "
1667 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1668 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1669 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1670 }
1671 return false;
1672 };
1673 TraverseWindowTree(func, true);
1674 WLOGFD("------ dump window info end -------");
1675 }
1676
DumpScreenWindowTree()1677 void WindowNodeContainer::DumpScreenWindowTree()
1678 {
1679 WLOGI("------ dump window info begin -------");
1680 WLOGI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation firstFrameCallback [ x y w h]");
1681 uint32_t zOrder = zOrder_;
1682 WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1683 Rect rect = node->GetWindowRect();
1684 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1685 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1686 WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1687 "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1688 windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1689 node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1690 node->firstFrameAvailable_, rect.posX_, rect.posY_, rect.width_, rect.height_);
1691 return false;
1692 };
1693 TraverseWindowTree(func, true);
1694 WLOGI("------ dump window info end -------");
1695 }
1696
IsVerticalDisplay(DisplayId displayId) const1697 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1698 {
1699 return DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).width_ <
1700 DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).height_;
1701 }
1702
ProcessWindowStateChange(WindowState state,WindowStateChangeReason reason)1703 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1704 {
1705 switch (reason) {
1706 case WindowStateChangeReason::KEYGUARD: {
1707 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1708 TraverseAndUpdateWindowState(state, topPriority);
1709 break;
1710 }
1711 default:
1712 return;
1713 }
1714 }
1715
TraverseAndUpdateWindowState(WindowState state,int32_t topPriority)1716 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1717 {
1718 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1719 for (auto& node : rootNodes) {
1720 UpdateWindowState(node, topPriority, state);
1721 }
1722 }
1723
UpdateWindowState(sptr<WindowNode> node,int32_t topPriority,WindowState state)1724 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1725 {
1726 if (node == nullptr) {
1727 return;
1728 }
1729 if (node->parent_ != nullptr && node->currentVisibility_) {
1730 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1731 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1732 if (node->GetWindowToken()) {
1733 node->GetWindowToken()->UpdateWindowState(state);
1734 }
1735 HandleKeepScreenOn(node, state);
1736 }
1737 }
1738 for (auto& childNode : node->children_) {
1739 UpdateWindowState(childNode, topPriority, state);
1740 }
1741 }
1742
HandleKeepScreenOn(const sptr<WindowNode> & node,WindowState state)1743 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1744 {
1745 if (node == nullptr) {
1746 WLOGFE("window is invalid");
1747 return;
1748 }
1749 if (state == WindowState::STATE_FROZEN) {
1750 HandleKeepScreenOn(node, false);
1751 } else if (state == WindowState::STATE_UNFROZEN) {
1752 HandleKeepScreenOn(node, node->IsKeepScreenOn());
1753 } else {
1754 // do nothing
1755 }
1756 }
1757
FindDividerNode() const1758 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1759 {
1760 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1761 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1762 return *iter;
1763 }
1764 }
1765 return nullptr;
1766 }
1767
RaiseSplitRelatedWindowToTop(sptr<WindowNode> & node)1768 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1769 {
1770 if (node == nullptr) {
1771 return;
1772 }
1773 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1774 if (windowPair == nullptr) {
1775 WLOGFE("Window pair is nullptr");
1776 return;
1777 }
1778 std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1779 RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1780 AssignZOrder();
1781 return;
1782 }
1783
RaiseZOrderForAppWindow(sptr<WindowNode> & node,sptr<WindowNode> & parentNode)1784 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1785 {
1786 if (node == nullptr) {
1787 return WMError::WM_ERROR_NULLPTR;
1788 }
1789 if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1790 WLOGE("Window %{public}u is already at top", node->GetWindowId());
1791 return WMError::WM_ERROR_INVALID_TYPE;
1792 }
1793
1794 if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1795 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1796 if (parentNode == nullptr) {
1797 WLOGFE("window type is invalid");
1798 return WMError::WM_ERROR_NULLPTR;
1799 }
1800 RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1801 if (parentNode->IsSplitMode()) {
1802 RaiseSplitRelatedWindowToTop(parentNode);
1803 } else if (parentNode->parent_ != nullptr) {
1804 RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1805 }
1806 } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1807 if (node->IsSplitMode()) {
1808 RaiseSplitRelatedWindowToTop(node);
1809 } else {
1810 // remote animation continuous start and exit allow parent is nullptr
1811 if (node->parent_ == nullptr) {
1812 WLOGFW("node parent is nullptr");
1813 return WMError::WM_OK;
1814 }
1815 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1816 }
1817 } else {
1818 // do nothing
1819 }
1820
1821 AssignZOrder();
1822 WLOGI("Raise app window zorder");
1823 DumpScreenWindowTreeByWinId(node->GetWindowId());
1824 return WMError::WM_OK;
1825 }
1826
GetNextFocusableWindow(uint32_t windowId) const1827 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1828 {
1829 sptr<WindowNode> nextFocusableWindow;
1830 bool previousFocusedWindowFound = false;
1831 WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1832 sptr<WindowNode> node) {
1833 if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1834 nextFocusableWindow = node;
1835 return true;
1836 }
1837 if (node->GetWindowId() == windowId) {
1838 previousFocusedWindowFound = true;
1839 }
1840 return false;
1841 };
1842 TraverseWindowTree(func, true);
1843 return nextFocusableWindow;
1844 }
1845
GetNextRotatableWindow(uint32_t windowId) const1846 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1847 {
1848 sptr<WindowNode> nextRotatableWindow;
1849 WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1850 sptr<WindowNode> node) {
1851 if (windowId != node->GetWindowId() &&
1852 WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1853 nextRotatableWindow = node;
1854 return true;
1855 }
1856 return false;
1857 };
1858 TraverseWindowTree(func, true);
1859 return nextRotatableWindow;
1860 }
1861
GetNextActiveWindow(uint32_t windowId) const1862 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1863 {
1864 auto currentNode = FindWindowNodeById(windowId);
1865 if (currentNode == nullptr) {
1866 WLOGFE("cannot find window id: %{public}u by tree", windowId);
1867 return nullptr;
1868 }
1869 WLOGFD("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1870 if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1871 for (auto& node : appWindowNode_->children_) {
1872 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1873 continue;
1874 }
1875 return node;
1876 }
1877 for (auto& node : belowAppWindowNode_->children_) {
1878 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1879 return node;
1880 }
1881 }
1882 } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1883 std::vector<sptr<WindowNode>> windowNodes;
1884 TraverseContainer(windowNodes);
1885 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1886 return node->GetWindowId() == windowId;
1887 });
1888 if (iter == windowNodes.end()) {
1889 WLOGFE("could not find this window");
1890 return nullptr;
1891 }
1892 int index = std::distance(windowNodes.begin(), iter);
1893 for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1894 if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1895 || !windowNodes[i]->currentVisibility_) {
1896 continue;
1897 }
1898 return windowNodes[i];
1899 }
1900 } else {
1901 // do nothing
1902 }
1903 WLOGFE("could not get next active window");
1904 return nullptr;
1905 }
1906
IsForbidDockSliceMove(DisplayId displayId) const1907 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1908 {
1909 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1910 if (windowPair == nullptr) {
1911 WLOGFE("window pair is nullptr");
1912 return true;
1913 }
1914 if (windowPair->IsForbidDockSliceMove()) {
1915 return true;
1916 }
1917 return false;
1918 }
1919
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1920 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1921 {
1922 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1923 if (windowPair == nullptr) {
1924 WLOGFE("window pair is nullptr");
1925 return false;
1926 }
1927 std::vector<int32_t> exitSplitPoints = windowPair->GetExitSplitPoints();
1928 if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1929 return false;
1930 }
1931 return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1932 }
1933
ExitSplitMode(DisplayId displayId)1934 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1935 {
1936 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1937 if (windowPair == nullptr) {
1938 WLOGFE("window pair is nullptr");
1939 return;
1940 }
1941 windowPair->ExitSplitMode();
1942 }
1943
MinimizeAllAppWindows(DisplayId displayId)1944 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1945 {
1946 WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1947 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1948 if (ret != WMError::WM_OK) {
1949 WLOGFE("Minimize all app window failed");
1950 }
1951 return;
1952 }
1953
GetDeskTopWindow()1954 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1955 {
1956 sptr<WindowNode> deskTop;
1957 WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1958 if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1959 deskTop = node;
1960 return true;
1961 }
1962 return false;
1963 };
1964 TraverseWindowTree(findDeskTopFunc, false);
1965 return deskTop;
1966 }
1967
HasPrivateWindow()1968 bool WindowNodeContainer::HasPrivateWindow()
1969 {
1970 std::vector<sptr<WindowNode>> windowNodes;
1971 TraverseContainer(windowNodes);
1972 for (const auto& node : windowNodes) {
1973 if (node && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION &&
1974 node->GetWindowProperty()->GetPrivacyMode()) {
1975 WLOGI("window name %{public}s", node->GetWindowName().c_str());
1976 return true;
1977 }
1978 }
1979 return false;
1980 }
1981
HasMainFullScreenWindowShown()1982 bool WindowNodeContainer::HasMainFullScreenWindowShown()
1983 {
1984 std::vector<sptr<WindowNode>> windowNodes;
1985 for (auto& node : appWindowNode_->children_) {
1986 TraverseWindowNode(node, windowNodes);
1987 }
1988 for (const auto& node : windowNodes) {
1989 if (node->currentVisibility_ &&
1990 WindowHelper::IsMainFullScreenWindow(node->GetWindowType(), node->GetWindowMode())) {
1991 return true;
1992 }
1993 }
1994 return false;
1995 }
1996
MinimizeOldestAppWindow()1997 void WindowNodeContainer::MinimizeOldestAppWindow()
1998 {
1999 for (auto& appNode : appWindowNode_->children_) {
2000 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2001 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2002 return;
2003 }
2004 }
2005 for (auto& appNode : aboveAppWindowNode_->children_) {
2006 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2007 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2008 return;
2009 }
2010 }
2011 WLOGD("no window needs to minimize");
2012 }
2013
MinimizeOldestMainFloatingWindow(uint32_t windowId)2014 void WindowNodeContainer::MinimizeOldestMainFloatingWindow(uint32_t windowId)
2015 {
2016 if (maxMainFloatingWindowNumber_ <= 0) {
2017 WLOGD("There is no limit at The number of floating window");
2018 return;
2019 }
2020
2021 auto windowNumber = GetMainFloatingWindowCount();
2022 if (windowNumber <= maxMainFloatingWindowNumber_) {
2023 WLOGD("The number of floating window is less then MaxFloatAppMainWindowNumber");
2024 return;
2025 }
2026 std::vector<sptr<WindowNode>> rootNodes = {
2027 appWindowNode_, aboveAppWindowNode_,
2028 };
2029 for (auto& root : rootNodes) {
2030 for (auto& appNode : root->children_) {
2031 WindowType windowType = appNode->GetWindowType();
2032 WindowMode windowMode = appNode->GetWindowMode();
2033 uint32_t winId = appNode->GetWindowId();
2034 if (windowId != winId && WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
2035 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2036 return;
2037 }
2038 }
2039 }
2040 WLOGD("no window needs to minimize");
2041 }
2042
ToggleShownStateForAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc,bool restore)2043 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
2044 std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
2045 {
2046 for (auto node : aboveAppWindowNode_->children_) {
2047 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
2048 node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
2049 return WMError::WM_DO_NOTHING;
2050 }
2051 }
2052 // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
2053 if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
2054 backupWindowIds_.clear();
2055 backupWindowMode_.clear();
2056 backupDisplaySplitWindowMode_.clear();
2057 backupDividerWindowRect_.clear();
2058 }
2059 if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
2060 WLOGD("backup");
2061 BackUpAllAppWindows();
2062 } else if (restore && !backupWindowIds_.empty()) {
2063 WLOGD("restore");
2064 RestoreAllAppWindows(restoreFunc);
2065 } else {
2066 WLOGD("do nothing because shown app windows is empty or backup windows is empty.");
2067 }
2068 WLOGD("ToggleShownStateForAllAppWindows");
2069 return WMError::WM_OK;
2070 }
2071
BackUpAllAppWindows()2072 void WindowNodeContainer::BackUpAllAppWindows()
2073 {
2074 std::set<DisplayId> displayIdSet;
2075 backupWindowMode_.clear();
2076 backupDisplaySplitWindowMode_.clear();
2077 std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
2078 for (auto& appNode : children) {
2079 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2080 continue;
2081 }
2082 auto windowMode = appNode->GetWindowMode();
2083 backupWindowMode_[appNode->GetWindowId()] = windowMode;
2084 if (WindowHelper::IsSplitWindowMode(windowMode)) {
2085 backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
2086 }
2087 displayIdSet.insert(appNode->GetDisplayId());
2088 }
2089 for (auto& appNode : children) {
2090 // exclude exceptional window
2091 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2092 WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
2093 continue;
2094 }
2095 // minimize window
2096 WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
2097 backupWindowIds_.emplace_back(appNode->GetWindowId());
2098 WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId(), true);
2099 wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
2100 auto task = [abilityToken]() {
2101 auto token = abilityToken.promote();
2102 if (token == nullptr) {
2103 WLOGFW("Ability token is null");
2104 return;
2105 }
2106 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
2107 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
2108 };
2109 WindowInnerManager::GetInstance().PostTask(task, "DoAbilityBackground");
2110 }
2111 backupDividerWindowRect_.clear();
2112 for (auto displayId : displayIdSet) {
2113 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2114 if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
2115 continue;
2116 }
2117 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
2118 }
2119 }
2120
RestoreAllAppWindows(std::function<bool (uint32_t,WindowMode)> restoreFunc)2121 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
2122 {
2123 std::vector<uint32_t> backupWindowIds(backupWindowIds_);
2124 auto displayIds = DisplayGroupInfo::GetInstance().GetAllDisplayIds();
2125 std::vector<sptr<WindowPair>> windowPairs;
2126 for (auto displayId : displayIds) {
2127 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2128 if (windowPair != nullptr) {
2129 if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
2130 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
2131 windowPair->SetAllSplitAppWindowsRestoring(true);
2132 }
2133 windowPairs.emplace_back(windowPair);
2134 }
2135 }
2136 for (auto windowId: backupWindowIds) {
2137 if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
2138 WLOGFE("restore %{public}u failed", windowId);
2139 continue;
2140 }
2141 WLOGFD("restore %{public}u", windowId);
2142 }
2143 for (auto windowPair : windowPairs) {
2144 windowPair->SetAllSplitAppWindowsRestoring(false);
2145 }
2146 layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
2147 backupWindowIds_.clear();
2148 backupWindowMode_.clear();
2149 backupDividerWindowRect_.clear();
2150 }
2151
IsAppWindowsEmpty() const2152 bool WindowNodeContainer::IsAppWindowsEmpty() const
2153 {
2154 return appWindowNode_->children_.empty();
2155 }
2156
MinimizeAppNodeExceptOptions(MinimizeReason reason,const std::vector<uint32_t> & exceptionalIds,const std::vector<WindowMode> & exceptionalModes)2157 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
2158 const std::vector<uint32_t> &exceptionalIds, const std::vector<WindowMode> &exceptionalModes)
2159 {
2160 if (appWindowNode_->children_.empty()) {
2161 return WMError::WM_OK;
2162 }
2163 for (auto& appNode : appWindowNode_->children_) {
2164 // exclude exceptional window
2165 if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
2166 std::find(exceptionalModes.begin(), exceptionalModes.end(),
2167 appNode->GetWindowMode()) != exceptionalModes.end() ||
2168 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2169 continue;
2170 }
2171 MinimizeApp::AddNeedMinimizeApp(appNode, reason);
2172 }
2173 return WMError::WM_OK;
2174 }
2175
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode> & node)2176 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
2177 {
2178 std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
2179 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
2180 return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
2181 }
2182
SwitchLayoutPolicy(WindowLayoutMode dstMode,DisplayId displayId,bool reorder)2183 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
2184 {
2185 WLOGD("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
2186 static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
2187 if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
2188 WLOGFE("invalid layout mode");
2189 return WMError::WM_ERROR_INVALID_PARAM;
2190 }
2191 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2192 if (windowPair == nullptr) {
2193 WLOGFE("Window pair is nullptr");
2194 return WMError::WM_ERROR_NULLPTR;
2195 }
2196 if (layoutMode_ != dstMode) {
2197 if (layoutMode_ == WindowLayoutMode::CASCADE) {
2198 windowPair->Clear();
2199 }
2200 layoutMode_ = dstMode;
2201 layoutPolicy_ = layoutPolicies_[dstMode];
2202 layoutPolicy_->Launch();
2203 DumpScreenWindowTree();
2204 } else {
2205 WLOGI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
2206 }
2207 if (reorder) {
2208 windowPair->Clear();
2209 layoutPolicy_->Reorder();
2210 DumpScreenWindowTree();
2211 }
2212 NotifyIfSystemBarTintChanged(displayId);
2213 NotifyDockWindowStateChanged(displayId);
2214 return WMError::WM_OK;
2215 }
2216
UpdateWindowModeSupportTypeWhenKeyguardChange(const sptr<WindowNode> & node,bool up)2217 void WindowNodeContainer::UpdateWindowModeSupportTypeWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
2218 {
2219 if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestWindowModeSupportType(),
2220 WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2221 WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
2222 return;
2223 }
2224 uint32_t windowModeSupportType;
2225 if (up) {
2226 windowModeSupportType = node->GetWindowModeSupportType() &
2227 (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
2228 } else {
2229 windowModeSupportType = node->GetWindowModeSupportType() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
2230 }
2231 node->SetWindowModeSupportType(windowModeSupportType);
2232 if (node->GetWindowToken() != nullptr) {
2233 node->GetWindowToken()->UpdateWindowModeSupportType(windowModeSupportType);
2234 }
2235 }
2236
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode> & node) const2237 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
2238 {
2239 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2240 return;
2241 }
2242
2243 if (isScreenLocked_) {
2244 node->priority_ = zorderPolicy_->GetWindowPriority(
2245 WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
2246 WLOGD("Raise input method float window priority when screen locked.");
2247 return;
2248 }
2249
2250 auto callingWindowId = node->GetCallingWindow();
2251 auto callingWindow = FindWindowNodeById(callingWindowId);
2252 if (callingWindowId == focusedWindow_ && callingWindow != nullptr) {
2253 auto callingWindowType = callingWindow->GetWindowType();
2254 auto callingWindowPriority = zorderPolicy_->GetWindowPriority(callingWindowType);
2255 auto inputMethodPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2256
2257 node->priority_ = (inputMethodPriority < callingWindowPriority) ?
2258 (callingWindowPriority + 1) : inputMethodPriority;
2259 WLOGFD("Reset input method float window priority to %{public}d.", node->priority_);
2260 return;
2261 }
2262
2263 auto focusWindow = FindWindowNodeById(focusedWindow_);
2264 if (focusWindow != nullptr && focusWindow->GetWindowType() == WindowType::WINDOW_TYPE_PANEL) {
2265 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_PANEL) + 1;
2266 WLOGFD("The input method float window should be higher than panel");
2267 }
2268 }
2269
ReZOrderShowWhenLockedWindows(bool up)2270 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
2271 {
2272 WLOGD("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
2273 std::vector<sptr<WindowNode>> needReZOrderNodes;
2274 auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
2275 auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
2276
2277 auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
2278 zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
2279
2280 for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
2281 if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
2282 needReZOrderNodes.emplace_back(*iter);
2283 iter = srcRoot->children_.erase(iter);
2284 } else {
2285 iter++;
2286 }
2287 }
2288 const int32_t floatingPriorityOffset = 1;
2289 for (auto& needReZOrderNode : needReZOrderNodes) {
2290 needReZOrderNode->priority_ = dstPriority;
2291 needReZOrderNode->parent_ = dstRoot;
2292 if (WindowHelper::IsMainFloatingWindow(needReZOrderNode->GetWindowType(),
2293 needReZOrderNode->GetWindowMode()) && isFloatWindowAboveFullWindow_) {
2294 needReZOrderNode->priority_ = dstPriority + floatingPriorityOffset;
2295 }
2296 auto parentNode = needReZOrderNode->parent_;
2297 auto position = parentNode->children_.end();
2298 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
2299 if ((*iter)->priority_ > needReZOrderNode->priority_) {
2300 position = iter;
2301 break;
2302 }
2303 }
2304
2305 UpdateWindowModeSupportTypeWhenKeyguardChange(needReZOrderNode, up);
2306
2307 parentNode->children_.insert(position, needReZOrderNode);
2308 if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
2309 needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
2310 // when change mode, need to reset shadow and radius
2311 WindowSystemEffect::SetWindowEffect(needReZOrderNode);
2312 if (needReZOrderNode->GetWindowToken() != nullptr) {
2313 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
2314 }
2315 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
2316 if (windowPair == nullptr) {
2317 WLOGFE("Window pair is nullptr");
2318 return;
2319 }
2320 windowPair->UpdateIfSplitRelated(needReZOrderNode);
2321 }
2322 WLOGD("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
2323 }
2324 }
2325
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2326 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2327 {
2328 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2329 !isScreenLocked_) {
2330 return;
2331 }
2332
2333 ReZOrderShowWhenLockedWindows(true);
2334 WLOGI("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
2335 }
2336
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2337 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2338 {
2339 // if keyguard window show, raise show when locked windows
2340 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2341 ReZOrderShowWhenLockedWindows(true);
2342 return;
2343 }
2344
2345 // if show when locked window show, raise itself when exist keyguard
2346 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2347 !isScreenLocked_) {
2348 return;
2349 }
2350
2351 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2352 node->parent_ = aboveAppWindowNode_;
2353 if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
2354 node->GetWindowProperty()->ResumeLastWindowMode();
2355 // when change mode, need to reset shadow and radius
2356 WindowSystemEffect::SetWindowEffect(node);
2357 if (node->GetWindowToken() != nullptr) {
2358 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2359 }
2360 }
2361 WLOGI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
2362 }
2363
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode> & node)2364 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2365 {
2366 // if keyguard window hide, drop show when locked windows
2367 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2368 ReZOrderShowWhenLockedWindows(false);
2369 AssignZOrder();
2370 }
2371 }
2372
TraverseWindowTree(const WindowNodeOperationFunc & func,bool isFromTopToBottom) const2373 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
2374 {
2375 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
2376 if (isFromTopToBottom) {
2377 std::reverse(rootNodes.begin(), rootNodes.end());
2378 }
2379
2380 for (const auto& node : rootNodes) {
2381 if (isFromTopToBottom) {
2382 for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
2383 if (TraverseFromTopToBottom(*iter, func)) {
2384 return;
2385 }
2386 }
2387 } else {
2388 for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
2389 if (TraverseFromBottomToTop(*iter, func)) {
2390 return;
2391 }
2392 }
2393 }
2394 }
2395 }
2396
TraverseFromTopToBottom(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const2397 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2398 {
2399 if (node == nullptr) {
2400 return false;
2401 }
2402 auto iterBegin = node->children_.rbegin();
2403 for (; iterBegin != node->children_.rend(); ++iterBegin) {
2404 if ((*iterBegin)->priority_ <= 0) {
2405 break;
2406 }
2407 if (func(*iterBegin)) {
2408 return true;
2409 }
2410 }
2411 if (func(node)) {
2412 return true;
2413 }
2414 for (; iterBegin != node->children_.rend(); ++iterBegin) {
2415 if (func(*iterBegin)) {
2416 return true;
2417 }
2418 }
2419 return false;
2420 }
2421
TraverseFromBottomToTop(sptr<WindowNode> node,const WindowNodeOperationFunc & func) const2422 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2423 {
2424 if (node == nullptr) {
2425 return false;
2426 }
2427 auto iterBegin = node->children_.begin();
2428 for (; iterBegin != node->children_.end(); ++iterBegin) {
2429 if ((*iterBegin)->priority_ >= 0) {
2430 break;
2431 }
2432 if (func(*iterBegin)) {
2433 return true;
2434 }
2435 }
2436 if (func(node)) {
2437 return true;
2438 }
2439 for (; iterBegin != node->children_.end(); ++iterBegin) {
2440 if (func(*iterBegin)) {
2441 return true;
2442 }
2443 }
2444 return false;
2445 }
2446
GetDisplayGroupRect() const2447 Rect WindowNodeContainer::GetDisplayGroupRect() const
2448 {
2449 return layoutPolicy_->GetDisplayGroupRect();
2450 }
2451
UpdateSizeChangeReason(sptr<WindowNode> & node,WindowMode srcMode,WindowMode dstMode)2452 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowMode srcMode, WindowMode dstMode)
2453 {
2454 if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2455 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2456 } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2457 node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2458 if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2459 node->SetRequestRect(node->GetWindowRect());
2460 }
2461 } else if (WindowHelper::IsFullScreenWindow(srcMode) && WindowHelper::IsSplitWindowMode(dstMode)) {
2462 node->SetWindowSizeChangeReason(WindowSizeChangeReason::FULL_TO_SPLIT);
2463 } else if (WindowHelper::IsSplitWindowMode(srcMode) && WindowHelper::IsFullScreenWindow(dstMode)) {
2464 node->SetWindowSizeChangeReason(WindowSizeChangeReason::SPLIT_TO_FULL);
2465 } else {
2466 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2467 }
2468 }
2469
SetWindowMode(sptr<WindowNode> & node,WindowMode dstMode)2470 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2471 {
2472 if (node == nullptr) {
2473 WLOGFE("could not find window");
2474 return WMError::WM_ERROR_NULLPTR;
2475 }
2476 WindowMode srcMode = node->GetWindowMode();
2477 if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2478 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2479 return WMError::WM_ERROR_INVALID_PARAM;
2480 }
2481
2482 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2483 if (windowPair == nullptr) {
2484 WLOGFE("Window pair is nullptr");
2485 return WMError::WM_ERROR_NULLPTR;
2486 }
2487
2488 WindowPairStatus status = windowPair->GetPairStatus();
2489 // when status is single primary or single secondary, split node is abandoned to set mode
2490 if (node->IsSplitMode() && (status == WindowPairStatus::SINGLE_PRIMARY ||
2491 status == WindowPairStatus::SINGLE_SECONDARY)) {
2492 return WMError::WM_ERROR_INVALID_OPERATION;
2493 }
2494 WMError res = WMError::WM_OK;
2495 UpdateSizeChangeReason(node, srcMode, dstMode);
2496 node->SetWindowMode(dstMode);
2497 windowPair->UpdateIfSplitRelated(node);
2498
2499 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2500 if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2501 NotifyDockWindowStateChanged(node, true);
2502 } else {
2503 NotifyDockWindowStateChanged(node, false);
2504 }
2505 }
2506
2507 if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2508 WindowHelper::IsAppWindow(node->GetWindowType())) {
2509 // minimize other app window.
2510 res = MinimizeStructuredAppWindowsExceptSelf(node);
2511 if (res != WMError::WM_OK) {
2512 return res;
2513 }
2514 }
2515 // when change mode, need to reset shadow and radius.
2516 WindowSystemEffect::SetWindowEffect(node);
2517
2518 // when change mode, need to reset MainFloatingWindow ZOrder.
2519 ResetWindowZOrderPriorityWhenSetMode(node, dstMode, srcMode);
2520 MinimizeOldestMainFloatingWindow(node->GetWindowId());
2521
2522 if (node->GetWindowToken() != nullptr) {
2523 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2524 }
2525 res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2526 if (res != WMError::WM_OK) {
2527 WLOGFE("Set window mode failed, update node failed");
2528 return res;
2529 }
2530 return WMError::WM_OK;
2531 }
2532
ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode> & node,const WindowMode & dstMode,const WindowMode & srcMode)2533 void WindowNodeContainer::ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode>& node,
2534 const WindowMode& dstMode, const WindowMode& srcMode)
2535 {
2536 if (!isFloatWindowAboveFullWindow_) {
2537 return;
2538 }
2539
2540 // reset node zorder priority.
2541 if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode)) {
2542 auto basePriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
2543 if (isScreenLocked_ &&
2544 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2545 basePriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2546 }
2547 node->priority_ = basePriority;
2548 }
2549
2550 if (!WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode) &&
2551 !WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode) &&
2552 !WindowHelper::IsSplitWindowMode(srcMode) &&
2553 !WindowHelper::IsSplitWindowMode(dstMode)) {
2554 return;
2555 }
2556
2557 // When set mode, all floating window should be checked and raise
2558 ResetAllMainFloatingWindowZOrder(node->parent_);
2559 if (node->parent_ != nullptr && node->GetWindowId() == focusedWindow_ &&
2560 WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode)) {
2561 // if current node is mainFloatingWIndow and foucsedWindow, it should be raised to top.
2562 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
2563 }
2564 AssignZOrder();
2565 }
2566
GetModeChangeHotZones(DisplayId displayId,ModeChangeHotZones & hotZones,const ModeChangeHotZonesConfig & config)2567 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2568 const ModeChangeHotZonesConfig& config)
2569 {
2570 const auto& displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
2571
2572 hotZones.fullscreen_.width_ = displayRect.width_;
2573 hotZones.fullscreen_.height_ = config.fullscreenRange_;
2574
2575 hotZones.primary_.width_ = config.primaryRange_;
2576 hotZones.primary_.height_ = displayRect.height_;
2577
2578 hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2579 hotZones.secondary_.width_ = config.secondaryRange_;
2580 hotZones.secondary_.height_ = displayRect.height_;
2581 }
2582
UpdateCameraFloatWindowStatus(const sptr<WindowNode> & node,bool isShowing)2583 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2584 {
2585 if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2586 WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2587 }
2588 }
2589
GetCurrentLayoutMode() const2590 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2591 {
2592 return layoutMode_;
2593 }
2594
RemoveSingleUserWindowNodes(int accountId)2595 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2596 {
2597 std::vector<sptr<WindowNode>> windowNodes;
2598 TraverseContainer(windowNodes);
2599 WLOGI("%{public}d", accountId);
2600 for (auto& windowNode : windowNodes) {
2601 int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2602 if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2603 WLOGD("skiped window %{public}s, windowId %{public}d uid %{public}d",
2604 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2605 continue;
2606 }
2607 WLOGD("remove window %{public}s, windowId %{public}d uid %{public}d",
2608 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2609 windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2610 if (windowNode->GetWindowToken()) {
2611 if (windowNode->surfaceNode_ != nullptr) {
2612 windowNode->surfaceNode_->SetVisible(true);
2613 }
2614 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2615 }
2616 }
2617 }
2618
TakeWindowPairSnapshot(DisplayId displayId)2619 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2620 {
2621 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2622 return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2623 }
2624
ClearWindowPairSnapshot(DisplayId displayId)2625 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2626 {
2627 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2628 if (windowPair == nullptr) {
2629 WLOGFE("Window pair is nullptr");
2630 return;
2631 }
2632 windowPair->ClearPairSnapshot();
2633 }
2634
SetWindowPairFrameGravity(DisplayId displayId,Gravity gravity)2635 void WindowNodeContainer::SetWindowPairFrameGravity(DisplayId displayId, Gravity gravity)
2636 {
2637 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2638 if (windowPair == nullptr) {
2639 WLOGFE("Window pair is nullptr");
2640 return;
2641 }
2642 std::vector<sptr<WindowNode>> windowNodes = windowPair->GetPairedWindows();
2643 for (auto& windowNode : windowNodes) {
2644 if (windowNode->surfaceNode_) {
2645 windowNode->surfaceNode_->SetFrameGravity(gravity);
2646 }
2647 }
2648 }
2649
IsScreenLocked()2650 bool WindowNodeContainer::IsScreenLocked()
2651 {
2652 return isScreenLocked_;
2653 }
2654
GetAnimateTransactionEnabled()2655 bool WindowNodeContainer::GetAnimateTransactionEnabled()
2656 {
2657 return isAnimateTransactionEnabled_;
2658 }
2659 } // namespace Rosen
2660 } // namespace OHOS
2661