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 WindowUIType WindowNodeContainer::windowUIType_ = WindowUIType::INVALID_WINDOW;
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 if (windowUIType_ != WindowUIType::PHONE_WINDOW) {
779 return false;
780 }
781 return WindowHelper::IsWindowFollowParent(type);
782 }
783
AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId, WindowUpdateType type, bool animationPlayed)784 bool WindowNodeContainer::AddNodeOnRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
785 WindowUpdateType type, bool animationPlayed)
786 {
787 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
788 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
789 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
790 WLOGI("no need to update RSTree");
791 return true;
792 }
793 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
794 WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", parentDisplayId: %{public}" PRIu64", "
795 "isMultiDisplay: %{public}d, animationPlayed: %{public}d",
796 node->GetWindowId(), displayId, parentDisplayId, isMultiDisplay, animationPlayed);
797 auto updateRSTreeFunc = [&]() {
798 if (!node->currentVisibility_) {
799 WLOGI("id: %{public}d invisible, no need update RS tree", node->GetWindowId());
800 return;
801 }
802
803 if (IsWindowFollowParent(node->GetWindowType())) {
804 auto& parentNode = node->parent_;
805 if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
806 node->surfaceNode_ != nullptr) {
807 node->surfaceNode_->SetTranslateX(node->GetWindowRect().posX_ - parentNode->GetWindowRect().posX_);
808 node->surfaceNode_->SetTranslateY(node->GetWindowRect().posY_ - parentNode->GetWindowRect().posY_);
809 node->surfaceNode_->SetVisible(true);
810 parentNode->surfaceNode_->AddChild(node->surfaceNode_, -1);
811 WLOGFD("Add surfaceNode to parent surfaceNode succeed.");
812 return;
813 }
814 }
815 auto& dms = DisplayManagerServiceInner::GetInstance();
816 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
817 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, true, isMultiDisplay);
818 for (auto& child : node->children_) {
819 if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
820 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, true, isMultiDisplay);
821 }
822 }
823 };
824
825 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
826 updateRSTreeFunc();
827 return true;
828 }
829
830 WindowGravity windowGravity;
831 uint32_t percent;
832 node->GetWindowGravity(windowGravity, percent);
833 if (node->EnableDefaultAnimation(animationPlayed)) {
834 WLOGFD("Add node with animation");
835 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
836 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
837 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc);
838 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
839 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
840 windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT &&
841 !animationPlayed) { // add keyboard with animation
842 auto timingProtocol = animationConfig_.keyboardAnimationIn_.duration_;
843 OpenInputMethodSyncTransaction();
844 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationIn_.curve_, updateRSTreeFunc);
845 CloseInputMethodSyncTransaction();
846 } else {
847 WLOGFD("add node without animation");
848 updateRSTreeFunc();
849 }
850 return true;
851 }
852
RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId, WindowUpdateType type, bool animationPlayed)853 bool WindowNodeContainer::RemoveNodeFromRSTree(sptr<WindowNode>& node, DisplayId displayId, DisplayId parentDisplayId,
854 WindowUpdateType type, bool animationPlayed)
855 {
856 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
857 if (node->GetWindowProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) ||
858 node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
859 WLOGI("no need to update RSTree");
860 return true;
861 }
862 bool isMultiDisplay = layoutPolicy_->IsMultiDisplay();
863 WLOGFD("Id: %{public}d, displayId: %{public}" PRIu64", isMultiDisplay: %{public}d, "
864 "parentDisplayId: %{public}" PRIu64", animationPlayed: %{public}d",
865 node->GetWindowId(), displayId, isMultiDisplay, parentDisplayId, animationPlayed);
866 auto updateRSTreeFunc = [&]() {
867 if (IsWindowFollowParent(node->GetWindowType())) {
868 const auto& parentNode = node->parent_;
869 if (parentNode != nullptr && parentNode->surfaceNode_ != nullptr &&
870 node->surfaceNode_ != nullptr) {
871 node->surfaceNode_->SetVisible(false);
872 parentNode->surfaceNode_->RemoveChild(node->surfaceNode_);
873 WLOGFD("Remove surfaceNode to parent surfaceNode succeed.");
874 return;
875 }
876 }
877 auto& dms = DisplayManagerServiceInner::GetInstance();
878 auto& surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_;
879 dms.UpdateRSTree(displayId, parentDisplayId, surfaceNode, false, isMultiDisplay);
880 for (auto& child : node->children_) {
881 if (child->currentVisibility_ && !IsWindowFollowParent(child->GetWindowType())) {
882 dms.UpdateRSTree(displayId, parentDisplayId, child->surfaceNode_, false, isMultiDisplay);
883 }
884 }
885 };
886
887 if (type != WindowUpdateType::WINDOW_UPDATE_ADDED && type != WindowUpdateType::WINDOW_UPDATE_REMOVED) {
888 updateRSTreeFunc();
889 return true;
890 }
891
892 WindowGravity windowGravity;
893 uint32_t percent;
894 node->GetWindowGravity(windowGravity, percent);
895 if (node->EnableDefaultAnimation(animationPlayed)) {
896 WLOGFD("remove with animation");
897 StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId());
898 if (node->surfaceNode_) {
899 node->surfaceNode_->SetFreeze(true);
900 }
901 wptr<WindowNode> weakNode(node);
902 RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_,
903 animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, [weakNode]() {
904 auto weakWindow = weakNode.promote();
905 if (weakWindow && weakWindow->surfaceNode_) {
906 weakWindow->surfaceNode_->SetFreeze(false);
907 }
908 });
909 FinishTrace(HITRACE_TAG_WINDOW_MANAGER);
910 } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
911 windowGravity != WindowGravity::WINDOW_GRAVITY_FLOAT && !animationPlayed) {
912 // remove keyboard with animation
913 OpenInputMethodSyncTransaction();
914 auto timingProtocol = animationConfig_.keyboardAnimationOut_.duration_;
915 RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationOut_.curve_, updateRSTreeFunc);
916 CloseInputMethodSyncTransaction();
917 } else {
918 updateRSTreeFunc();
919 }
920 return true;
921 }
922
Destroy()923 const std::vector<uint32_t>& WindowNodeContainer::Destroy()
924 {
925 // clear vector cache completely, swap with empty vector
926 auto emptyVector = std::vector<uint32_t>();
927 removedIds_.swap(emptyVector);
928 for (auto& node : belowAppWindowNode_->children_) {
929 DestroyWindowNode(node, removedIds_);
930 }
931 for (auto& node : appWindowNode_->children_) {
932 DestroyWindowNode(node, removedIds_);
933 }
934 for (auto& node : aboveAppWindowNode_->children_) {
935 DestroyWindowNode(node, removedIds_);
936 }
937 return removedIds_;
938 }
939
FindRoot(WindowType type) const940 sptr<WindowNode> WindowNodeContainer::FindRoot(WindowType type) const
941 {
942 if (WindowHelper::IsAppWindow(type) || type == WindowType::WINDOW_TYPE_DOCK_SLICE ||
943 type == WindowType::WINDOW_TYPE_APP_COMPONENT || type == WindowType::WINDOW_TYPE_PLACEHOLDER ||
944 type == WindowType::WINDOW_TYPE_DIALOG) {
945 return appWindowNode_;
946 }
947 if (WindowHelper::IsBelowSystemWindow(type)) {
948 return belowAppWindowNode_;
949 }
950 if (WindowHelper::IsAboveSystemWindow(type)) {
951 return aboveAppWindowNode_;
952 }
953 return nullptr;
954 }
955
FindWindowNodeById(uint32_t id) const956 sptr<WindowNode> WindowNodeContainer::FindWindowNodeById(uint32_t id) const
957 {
958 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
959 for (const auto& rootNode : rootNodes) {
960 for (auto& node : rootNode->children_) {
961 if (node->GetWindowId() == id) {
962 return node;
963 }
964 for (auto& subNode : node->children_) {
965 if (subNode->GetWindowId() == id) {
966 return subNode;
967 }
968 }
969 }
970 }
971 return nullptr;
972 }
973
UpdateFocusStatus(uint32_t id, bool focused)974 void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused)
975 {
976 auto node = FindWindowNodeById(id);
977 if (node == nullptr) {
978 WLOGFW("cannot find focused window id:%{public}d", id);
979 return;
980 }
981 if (focused) {
982 focusedPid_ = node->GetCallingPid();
983 }
984 node->isFocused_ = focused;
985 // change focus window shadow
986 WindowSystemEffect::SetWindowShadow(node);
987 if (node->GetCallingPid() == 0) {
988 WLOGFW("focused window is starting window, no need notify");
989 return;
990 }
991
992 if (focused && node->GetWindowProperty() != nullptr) {
993 AbilityInfo info = node->GetWindowProperty()->GetAbilityInfo();
994 WLOGFD("current focus window: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
995 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", id,
996 node->GetWindowProperty()->GetWindowName().c_str(), info.bundleName_.c_str(), info.abilityName_.c_str(),
997 node->GetCallingPid(), node->GetCallingUid());
998 uint64_t focusNodeId = 0; // 0 means invalid
999 if (node->surfaceNode_ == nullptr) {
1000 WLOGFW("focused window surfaceNode is null");
1001 } else {
1002 focusNodeId = node->surfaceNode_->GetId();
1003 }
1004 FocusAppInfo appInfo =
1005 { node->GetCallingPid(), node->GetCallingUid(), info.bundleName_, info.abilityName_, focusNodeId };
1006 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
1007 }
1008 if (node->GetWindowToken()) {
1009 node->GetWindowToken()->UpdateFocusStatus(focused);
1010 }
1011 if (node->abilityToken_ == nullptr) {
1012 WLOGW("AbilityToken is null, window : %{public}d", id);
1013 }
1014 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(node->GetWindowId(), node->GetDisplayId(),
1015 node->GetCallingPid(), node->GetCallingUid(), node->GetWindowType(), node->abilityToken_);
1016 WindowManagerAgentController::GetInstance().UpdateFocusChangeInfo(
1017 focusChangeInfo, focused);
1018 }
1019
UpdateActiveStatus(uint32_t id, bool isActive)1020 void WindowNodeContainer::UpdateActiveStatus(uint32_t id, bool isActive)
1021 {
1022 auto node = FindWindowNodeById(id);
1023 if (node == nullptr) {
1024 WLOGFE("cannot find active window id: %{public}d", id);
1025 return;
1026 }
1027 if (isActive) {
1028 activePid_ = node->GetCallingPid();
1029 }
1030 if (node->GetWindowToken()) {
1031 node->GetWindowToken()->UpdateActiveStatus(isActive);
1032 }
1033 }
1034
UpdateBrightness(uint32_t id, bool byRemoved)1035 void WindowNodeContainer::UpdateBrightness(uint32_t id, bool byRemoved)
1036 {
1037 auto node = FindWindowNodeById(id);
1038 if (node == nullptr) {
1039 WLOGFE("cannot find active window id: %{public}d", id);
1040 return;
1041 }
1042
1043 if (!byRemoved) {
1044 if (!WindowHelper::IsAppWindow(node->GetWindowType())) {
1045 return;
1046 }
1047 }
1048 WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), node->GetBrightness());
1049 if (std::fabs(node->GetBrightness() - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
1050 if (GetDisplayBrightness() != node->GetBrightness()) {
1051 WLOGI("adjust brightness with default value");
1052 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1053 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
1054 #endif
1055 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
1056 }
1057 SetBrightnessWindow(INVALID_WINDOW_ID);
1058 } else {
1059 if (GetDisplayBrightness() != node->GetBrightness()) {
1060 WLOGI("adjust brightness with value: %{public}u", ToOverrideBrightness(node->GetBrightness()));
1061 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
1062 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
1063 ToOverrideBrightness(node->GetBrightness()));
1064 #endif
1065 SetDisplayBrightness(node->GetBrightness());
1066 }
1067 SetBrightnessWindow(node->GetWindowId());
1068 }
1069 }
1070
AssignZOrder()1071 void WindowNodeContainer::AssignZOrder()
1072 {
1073 zOrder_ = 0;
1074 WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
1075 if (!node->leashWinSurfaceNode_ && !node->surfaceNode_ && !node->startingWinSurfaceNode_) {
1076 ++zOrder_;
1077 WLOGFE("Id: %{public}u has no surface nodes", node->GetWindowId());
1078 return false;
1079 }
1080 if (node->leashWinSurfaceNode_ != nullptr) {
1081 ++zOrder_;
1082 node->leashWinSurfaceNode_->SetPositionZ(zOrder_);
1083 }
1084
1085 if (node->surfaceNode_ != nullptr) {
1086 ++zOrder_;
1087 node->surfaceNode_->SetPositionZ(zOrder_);
1088 node->zOrder_ = zOrder_;
1089 }
1090 // make sure starting window above app
1091 if (node->startingWinSurfaceNode_ != nullptr) {
1092 ++zOrder_;
1093 node->startingWinSurfaceNode_->SetPositionZ(zOrder_);
1094 }
1095 return false;
1096 };
1097 TraverseWindowTree(func, false);
1098 displayGroupController_->UpdateDisplayGroupWindowTree();
1099 }
1100
SetFocusWindow(uint32_t windowId)1101 WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
1102 {
1103 if (focusedWindow_ == windowId) {
1104 WLOGI("Focus window not change, id: %{public}u, %{public}d", windowId, focusedPid_);
1105 // StartingWindow can be focused and this pid is 0, then notify info in UpdateFocusStatus.
1106 // This info is invalid, so we must notify again when first frame callback.
1107 if (focusedPid_ == 0) {
1108 UpdateFocusStatus(windowId, true);
1109 }
1110 return WMError::WM_DO_NOTHING;
1111 }
1112 UpdateFocusStatus(focusedWindow_, false);
1113 focusedWindow_ = windowId;
1114 UpdateFocusStatus(focusedWindow_, true);
1115 return WMError::WM_OK;
1116 }
1117
GetFocusWindow() const1118 uint32_t WindowNodeContainer::GetFocusWindow() const
1119 {
1120 return focusedWindow_;
1121 }
1122
SetActiveWindow(uint32_t windowId, bool byRemoved)1123 WMError WindowNodeContainer::SetActiveWindow(uint32_t windowId, bool byRemoved)
1124 {
1125 if (activeWindow_ == windowId) {
1126 WLOGI("Active window not change, id: %{public}u, %{public}d", windowId, activePid_);
1127 if (activePid_ == 0) {
1128 UpdateActiveStatus(windowId, true);
1129 }
1130 return WMError::WM_DO_NOTHING;
1131 }
1132 UpdateActiveStatus(activeWindow_, false);
1133 activeWindow_ = windowId;
1134 UpdateActiveStatus(activeWindow_, true);
1135 UpdateBrightness(activeWindow_, byRemoved);
1136 return WMError::WM_OK;
1137 }
1138
SetDisplayBrightness(float brightness)1139 void WindowNodeContainer::SetDisplayBrightness(float brightness)
1140 {
1141 displayBrightness_ = brightness;
1142 }
1143
GetDisplayBrightness() const1144 float WindowNodeContainer::GetDisplayBrightness() const
1145 {
1146 return displayBrightness_;
1147 }
1148
SetBrightnessWindow(uint32_t windowId)1149 void WindowNodeContainer::SetBrightnessWindow(uint32_t windowId)
1150 {
1151 brightnessWindow_ = windowId;
1152 }
1153
GetBrightnessWindow() const1154 uint32_t WindowNodeContainer::GetBrightnessWindow() const
1155 {
1156 return brightnessWindow_;
1157 }
1158
ToOverrideBrightness(float brightness)1159 uint32_t WindowNodeContainer::ToOverrideBrightness(float brightness)
1160 {
1161 return static_cast<uint32_t>(brightness * MAX_BRIGHTNESS);
1162 }
1163
GetActiveWindow() const1164 uint32_t WindowNodeContainer::GetActiveWindow() const
1165 {
1166 return activeWindow_;
1167 }
1168
GetLayoutPolicy() const1169 sptr<WindowLayoutPolicy> WindowNodeContainer::GetLayoutPolicy() const
1170 {
1171 return layoutPolicy_;
1172 }
1173
GetAvoidController() const1174 sptr<AvoidAreaController> WindowNodeContainer::GetAvoidController() const
1175 {
1176 return avoidController_;
1177 }
1178
GetDisplayGroupController() const1179 sptr<DisplayGroupController> WindowNodeContainer::GetDisplayGroupController() const
1180 {
1181 return displayGroupController_;
1182 }
1183
GetRootNode(WindowRootNodeType type) const1184 sptr<WindowNode> WindowNodeContainer::GetRootNode(WindowRootNodeType type) const
1185 {
1186 if (type == WindowRootNodeType::ABOVE_WINDOW_NODE) {
1187 return aboveAppWindowNode_;
1188 } else if (type == WindowRootNodeType::APP_WINDOW_NODE) {
1189 return appWindowNode_;
1190 } else if (type == WindowRootNodeType::BELOW_WINDOW_NODE) {
1191 return belowAppWindowNode_;
1192 }
1193 return nullptr;
1194 }
1195
HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)1196 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, bool requireLock)
1197 {
1198 #ifdef POWER_MANAGER_ENABLE
1199 if (requireLock && node->keepScreenLock_ == nullptr) {
1200 // reset ipc identity
1201 std::string identity = IPCSkeleton::ResetCallingIdentity();
1202 node->keepScreenLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(node->GetWindowName(),
1203 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
1204 // set ipc identity to raw
1205 IPCSkeleton::SetCallingIdentity(identity);
1206 }
1207 if (node->keepScreenLock_ == nullptr) {
1208 return;
1209 }
1210 WLOGI("keep screen on: [%{public}s, %{public}d]", node->GetWindowName().c_str(), requireLock);
1211 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "container:HandleKeepScreenOn(%s, %d)",
1212 node->GetWindowName().c_str(), requireLock);
1213 ErrCode res;
1214 // reset ipc identity
1215 std::string identity = IPCSkeleton::ResetCallingIdentity();
1216 if (requireLock) {
1217 res = node->keepScreenLock_->Lock();
1218 } else {
1219 res = node->keepScreenLock_->UnLock();
1220 }
1221 // set ipc identity to raw
1222 IPCSkeleton::SetCallingIdentity(identity);
1223 if (res != ERR_OK) {
1224 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]", requireLock, res);
1225 }
1226 #endif
1227 }
1228
IsAboveSystemBarNode(sptr<WindowNode> node) const1229 bool WindowNodeContainer::IsAboveSystemBarNode(sptr<WindowNode> node) const
1230 {
1231 int32_t curPriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
1232 if ((curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_STATUS_BAR)) &&
1233 (curPriority > zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_NAVIGATION_BAR))) {
1234 return true;
1235 }
1236 return false;
1237 }
1238
IsSplitImmersiveNode(sptr<WindowNode> node) const1239 bool WindowNodeContainer::IsSplitImmersiveNode(sptr<WindowNode> node) const
1240 {
1241 auto type = node->GetWindowType();
1242 return node->IsSplitMode() || type == WindowType::WINDOW_TYPE_DOCK_SLICE;
1243 }
1244
GetExpectImmersiveProperty(DisplayId id, sptr<WindowNode>& triggerWindow) const1245 std::unordered_map<WindowType, SystemBarProperty> WindowNodeContainer::GetExpectImmersiveProperty(DisplayId id,
1246 sptr<WindowNode>& triggerWindow) const
1247 {
1248 std::unordered_map<WindowType, SystemBarProperty> sysBarPropMap {
1249 { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty() },
1250 { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() },
1251 };
1252
1253 std::vector<sptr<WindowNode>> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ };
1254 if (layoutMode_ == WindowLayoutMode::TILE) {
1255 rootNodes = { aboveAppWindowNode_, belowAppWindowNode_ };
1256 }
1257
1258 for (const auto& node : rootNodes) {
1259 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); ++iter) {
1260 auto& sysBarPropMapNode = (*iter)->GetSystemBarProperty();
1261 if (IsAboveSystemBarNode(*iter)) {
1262 continue;
1263 }
1264 if (WindowHelper::IsFullScreenWindow((*iter)->GetWindowMode())
1265 && (*iter)->GetWindowType() != WindowType::WINDOW_TYPE_PANEL) {
1266 auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(id);
1267 if (displayInfo && WmsUtils::IsExpectedRotateLandscapeWindow((*iter)->GetRequestedOrientation(),
1268 displayInfo->GetDisplayOrientation(), (*iter)->GetWindowFlags())) {
1269 WLOGFI("Horizontal window id: %{public}d make it immersive", (*iter)->GetWindowId());
1270 for (auto it : sysBarPropMap) {
1271 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1272 sysBarPropMap[it.first].enable_ = false;
1273 }
1274 } else {
1275 WLOGFD("Top immersive window id: %{public}d. Use full immersive prop", (*iter)->GetWindowId());
1276 for (auto it : sysBarPropMap) {
1277 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1278 }
1279 triggerWindow = (*iter);
1280 }
1281 return sysBarPropMap;
1282 } else if (IsSplitImmersiveNode(*iter)) {
1283 WLOGFD("Top split window id: %{public}d. Use split immersive prop", (*iter)->GetWindowId());
1284 for (auto it : sysBarPropMap) {
1285 sysBarPropMap[it.first] = (sysBarPropMapNode.find(it.first))->second;
1286 sysBarPropMap[it.first].enable_ = false;
1287 }
1288 return sysBarPropMap;
1289 }
1290 }
1291 }
1292
1293 WLOGFD("No immersive window on top. Use default systembar Property");
1294 return sysBarPropMap;
1295 }
1296
NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node, const AvoidControlType avoidType) const1297 void WindowNodeContainer::NotifyIfAvoidAreaChanged(const sptr<WindowNode>& node,
1298 const AvoidControlType avoidType) const
1299 {
1300 auto checkFunc = [this](sptr<WindowNode> node) {
1301 return CheckWindowNodeWhetherInWindowTree(node);
1302 };
1303 avoidController_->ProcessWindowChange(node, avoidType, checkFunc);
1304 if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) {
1305 NotifyIfSystemBarRegionChanged(node->GetDisplayId());
1306 } else {
1307 NotifyIfSystemBarTintChanged(node->GetDisplayId());
1308 }
1309
1310 NotifyIfKeyboardRegionChanged(node, avoidType);
1311 }
1312
BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const1313 void WindowNodeContainer::BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const
1314 {
1315 avoidController_->SetFlagForProcessWindowChange(true);
1316 }
1317
ProcessWindowAvoidAreaChangeWhenDisplayChange() const1318 void WindowNodeContainer::ProcessWindowAvoidAreaChangeWhenDisplayChange() const
1319 {
1320 avoidController_->SetFlagForProcessWindowChange(false);
1321 auto checkFunc = [this](sptr<WindowNode> node) {
1322 return CheckWindowNodeWhetherInWindowTree(node);
1323 };
1324 WindowNodeOperationFunc func = [avoidController = avoidController_, &checkFunc](sptr<WindowNode> node) {
1325 avoidController->ProcessWindowChange(node, AvoidControlType::AVOID_NODE_UPDATE, checkFunc);
1326 return false;
1327 };
1328 TraverseWindowTree(func, true);
1329 }
1330
NotifyIfSystemBarTintChanged(DisplayId displayId) const1331 void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) const
1332 {
1333 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1334 sptr<WindowNode> triggerWindow = nullptr;
1335 auto expectSystemBarProp = GetExpectImmersiveProperty(displayId, triggerWindow);
1336 JudgeToReportSystemBarInfo(triggerWindow, expectSystemBarProp);
1337 SystemBarRegionTints tints;
1338 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1339 for (auto it : sysBarTintMap) {
1340 auto expectProp = expectSystemBarProp.find(it.first)->second;
1341 if (it.second.prop_ == expectProp) {
1342 continue;
1343 }
1344 WLOGFD("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x",
1345 static_cast<int32_t>(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_);
1346 sysBarTintMap[it.first].prop_ = expectProp;
1347 sysBarTintMap[it.first].type_ = it.first;
1348 tints.emplace_back(sysBarTintMap[it.first]);
1349 }
1350 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1351 }
1352
JudgeToReportSystemBarInfo(const sptr<WindowNode> window, const std::unordered_map<WindowType, SystemBarProperty>& systemBarPropInfo) const1353 void WindowNodeContainer::JudgeToReportSystemBarInfo(const sptr<WindowNode> window,
1354 const std::unordered_map<WindowType, SystemBarProperty>& systemBarPropInfo) const
1355 {
1356 if (window == nullptr || !WindowHelper::IsMainWindow(window->GetWindowType())) {
1357 WLOGFD("No need to report");
1358 return;
1359 }
1360
1361 // 2 means the must size of systemBarPropInfo.
1362 if (systemBarPropInfo.size() != 2) {
1363 return;
1364 }
1365
1366 auto bundleName = window->abilityInfo_.bundleName_;
1367 auto abilityName = window->abilityInfo_.abilityName_;
1368 auto navigationItor = systemBarPropInfo.find(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
1369 if (navigationItor != systemBarPropInfo.end() && !navigationItor->second.enable_) {
1370 WindowInfoReporter::GetInstance().InsertNavigationBarReportInfo(bundleName, abilityName);
1371 WLOGFD("the navigation bar is disabled by window. windowId:[%{public}u]", window->GetWindowId());
1372 }
1373 }
1374
NotifyIfSystemBarRegionChanged(DisplayId displayId) const1375 void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) const
1376 {
1377 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1378 SystemBarRegionTints tints;
1379 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1380 SysBarNodeMap& sysBarNodeMap = displayGroupController_->sysBarNodeMaps_[displayId];
1381 for (auto it : sysBarTintMap) { // split screen mode not support yet
1382 auto sysNode = sysBarNodeMap[it.first];
1383 if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) {
1384 continue;
1385 }
1386 const Rect& newRegion = sysNode->GetWindowRect();
1387 sysBarTintMap[it.first].region_ = newRegion;
1388 sysBarTintMap[it.first].type_ = it.first;
1389 tints.emplace_back(sysBarTintMap[it.first]);
1390 WLOGD("system bar region update, type: %{public}d" \
1391 "region: [%{public}d, %{public}d, %{public}d, %{public}d]",
1392 static_cast<int32_t>(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_);
1393 }
1394 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1395 }
1396
NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node, const AvoidControlType avoidType) const1397 void WindowNodeContainer::NotifyIfKeyboardRegionChanged(const sptr<WindowNode>& node,
1398 const AvoidControlType avoidType) const
1399 {
1400 WindowGravity windowGravity;
1401 uint32_t percent;
1402 node->GetWindowGravity(windowGravity, percent);
1403 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
1404 windowGravity == WindowGravity::WINDOW_GRAVITY_FLOAT) {
1405 WLOGFD("windowType: %{public}u", node->GetWindowType());
1406 return;
1407 }
1408
1409 auto callingWindow = FindWindowNodeById(node->GetCallingWindow());
1410 if (callingWindow == nullptr) {
1411 WLOGD("callingWindow: %{public}u does not be set", node->GetCallingWindow());
1412 callingWindow = FindWindowNodeById(GetFocusWindow());
1413 }
1414 if (callingWindow == nullptr || callingWindow->GetWindowToken() == nullptr) {
1415 WLOGE("does not have correct callingWindow for input method window");
1416 return;
1417 }
1418 const WindowMode callingWindowMode = callingWindow->GetWindowMode();
1419 if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
1420 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1421 callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1422 const Rect keyRect = node->GetWindowRect();
1423 const Rect callingRect = callingWindow->GetWindowRect();
1424 if (WindowHelper::IsEmptyRect(WindowHelper::GetOverlap(callingRect, keyRect, 0, 0))) {
1425 WLOGFD("no overlap between two windows");
1426 return;
1427 }
1428 Rect overlapRect = { 0, 0, 0, 0 };
1429 if (avoidType == AvoidControlType::AVOID_NODE_ADD || avoidType == AvoidControlType::AVOID_NODE_UPDATE) {
1430 overlapRect = WindowHelper::GetOverlap(keyRect, callingRect, callingRect.posX_, callingRect.posY_);
1431 }
1432 double textFieldPositionY = 0.0;
1433 double textFieldHeight = 0.0;
1434 if (node->GetWindowProperty() != nullptr) {
1435 textFieldPositionY = node->GetWindowProperty()->GetTextFieldPositionY();
1436 textFieldHeight = node->GetWindowProperty()->GetTextFieldHeight();
1437 }
1438 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
1439 overlapRect, textFieldPositionY, textFieldHeight);
1440 if (isAnimateTransactionEnabled_) {
1441 auto syncTransactionController = RSSyncTransactionController::GetInstance();
1442 if (syncTransactionController) {
1443 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info,
1444 syncTransactionController->GetRSTransaction());
1445 }
1446 } else {
1447 callingWindow->GetWindowToken()->UpdateOccupiedAreaChangeInfo(info);
1448 }
1449
1450 WLOGD("keyboard size change callingWindow: [%{public}s, %{public}u], "
1451 "overlap rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1452 callingWindow->GetWindowName().c_str(), callingWindow->GetWindowId(),
1453 overlapRect.posX_, overlapRect.posY_, overlapRect.width_, overlapRect.height_);
1454 return;
1455 }
1456 WLOGFE("does not have correct callingWindowMode for input method window");
1457 }
1458
NotifySystemBarTints(std::vector<DisplayId> displayIdVec)1459 void WindowNodeContainer::NotifySystemBarTints(std::vector<DisplayId> displayIdVec)
1460 {
1461 if (displayIdVec.size() != displayGroupController_->sysBarTintMaps_.size()) {
1462 WLOGE("[Immersive] the number of display is error");
1463 }
1464
1465 for (auto displayId : displayIdVec) {
1466 SystemBarRegionTints tints;
1467 SysBarTintMap& sysBarTintMap = displayGroupController_->sysBarTintMaps_[displayId];
1468 for (auto it : sysBarTintMap) {
1469 WLOGI("[Immersive] systembar tints, T: %{public}d, " \
1470 "V: %{public}d, C: %{public}x | %{public}x, " \
1471 "R: [%{public}d, %{public}d, %{public}d, %{public}d]",
1472 static_cast<int32_t>(it.first),
1473 sysBarTintMap[it.first].prop_.enable_,
1474 sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_,
1475 sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_,
1476 sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_);
1477 tints.push_back(sysBarTintMap[it.first]);
1478 }
1479 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1480 }
1481 }
1482
NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)1483 void WindowNodeContainer::NotifyDockWindowStateChanged(sptr<WindowNode>& node, bool isEnable)
1484 {
1485 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1486 WLOGFD("[Immersive] begin isEnable: %{public}d", isEnable);
1487 if (isEnable) {
1488 for (auto& windowNode : appWindowNode_->children_) {
1489 if (windowNode->GetWindowId() == node->GetWindowId()) {
1490 continue;
1491 }
1492 if (!WindowHelper::IsFloatingWindow(windowNode->GetWindowMode())) {
1493 return;
1494 }
1495 }
1496 }
1497 SystemBarProperty prop;
1498 prop.enable_ = isEnable;
1499 SystemBarRegionTint tint;
1500 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1501 tint.prop_ = prop;
1502 SystemBarRegionTints tints;
1503 tints.push_back(tint);
1504 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints);
1505 }
1506
NotifyDockWindowStateChanged(DisplayId displayId)1507 void WindowNodeContainer::NotifyDockWindowStateChanged(DisplayId displayId)
1508 {
1509 HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER);
1510 bool isEnable = true;
1511 for (auto& windowNode : appWindowNode_->children_) {
1512 if (WindowHelper::IsSplitWindowMode(windowNode->GetWindowMode()) ||
1513 WindowHelper::IsFullScreenWindow(windowNode->GetWindowMode())) {
1514 isEnable = false;
1515 break;
1516 }
1517 }
1518 WLOGFD("[Immersive] display %{public}" PRIu64" begin isEnable: %{public}d", displayId, isEnable);
1519 SystemBarProperty prop;
1520 prop.enable_ = isEnable;
1521 SystemBarRegionTint tint;
1522 tint.type_ = WindowType::WINDOW_TYPE_LAUNCHER_DOCK;
1523 tint.prop_ = prop;
1524 SystemBarRegionTints tints;
1525 tints.push_back(tint);
1526 WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints);
1527 }
1528
UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)1529 void WindowNodeContainer::UpdateAvoidAreaListener(sptr<WindowNode>& windowNode, bool haveAvoidAreaListener)
1530 {
1531 avoidController_->UpdateAvoidAreaListener(windowNode, haveAvoidAreaListener);
1532 }
1533
IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const1534 bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootNode) const
1535 {
1536 if (rootNode->children_.empty()) {
1537 WLOGFE("root does not have any node");
1538 return false;
1539 }
1540 auto node = *(rootNode->children_.rbegin());
1541 if (node == nullptr) {
1542 WLOGFE("window tree does not have any node");
1543 return false;
1544 }
1545
1546 for (auto iter = node->children_.rbegin(); iter < node->children_.rend(); iter++) {
1547 if ((*iter)->priority_ > 0) {
1548 return (*iter)->GetWindowId() == windowId;
1549 } else {
1550 break;
1551 }
1552 }
1553 return node->GetWindowId() == windowId;
1554 }
1555
RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes, std::vector<sptr<WindowNode>>& windowNodes)1556 void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
1557 std::vector<sptr<WindowNode>>& windowNodes)
1558 {
1559 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
1560 uint32_t wid = (*iter)->GetWindowId();
1561 auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
1562 [wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
1563 if (orderedIter != orderedNodes.end()) {
1564 iter = windowNodes.erase(iter);
1565 } else {
1566 iter++;
1567 }
1568 }
1569 for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
1570 UpdateWindowTree(*iter);
1571 }
1572 return;
1573 }
1574
RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)1575 void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector<sptr<WindowNode>>& windowNodes)
1576 {
1577 if (windowNodes.empty()) {
1578 WLOGFE("windowNodes is empty!");
1579 return;
1580 }
1581 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
1582 [windowId](sptr<WindowNode> node) {
1583 return node->GetWindowId() == windowId;
1584 });
1585 // raise app node window to top
1586 if (iter != windowNodes.end()) {
1587 sptr<WindowNode> node = *iter;
1588 windowNodes.erase(iter);
1589 UpdateWindowTree(node);
1590 WLOGD("raise window to top %{public}u", node->GetWindowId());
1591 }
1592 }
1593
TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const1594 void WindowNodeContainer::TraverseContainer(std::vector<sptr<WindowNode>>& windowNodes) const
1595 {
1596 for (auto& node : belowAppWindowNode_->children_) {
1597 TraverseWindowNode(node, windowNodes);
1598 }
1599 for (auto& node : appWindowNode_->children_) {
1600 TraverseWindowNode(node, windowNodes);
1601 }
1602 for (auto& node : aboveAppWindowNode_->children_) {
1603 TraverseWindowNode(node, windowNodes);
1604 }
1605 std::reverse(windowNodes.begin(), windowNodes.end());
1606 }
1607
TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const1608 void WindowNodeContainer::TraverseWindowNode(sptr<WindowNode>& node, std::vector<sptr<WindowNode>>& windowNodes) const
1609 {
1610 if (node == nullptr) {
1611 return;
1612 }
1613 auto iter = node->children_.begin();
1614 for (; iter < node->children_.end(); ++iter) {
1615 if ((*iter)->priority_ < 0) {
1616 windowNodes.emplace_back(*iter);
1617 } else {
1618 break;
1619 }
1620 }
1621 windowNodes.emplace_back(node);
1622 for (; iter < node->children_.end(); ++iter) {
1623 windowNodes.emplace_back(*iter);
1624 }
1625 }
1626
GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const1627 AvoidArea WindowNodeContainer::GetAvoidAreaByType(const sptr<WindowNode>& node, AvoidAreaType avoidAreaType) const
1628 {
1629 if (CheckWindowNodeWhetherInWindowTree(node)) {
1630 return avoidController_->GetAvoidAreaByType(node, avoidAreaType);
1631 }
1632 return {};
1633 }
1634
CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const1635 bool WindowNodeContainer::CheckWindowNodeWhetherInWindowTree(const sptr<WindowNode>& node) const
1636 {
1637 bool isInWindowTree = false;
1638 WindowNodeOperationFunc func = [&node, &isInWindowTree](sptr<WindowNode> windowNode) {
1639 if (node->GetWindowId() == windowNode->GetWindowId()) {
1640 isInWindowTree = true;
1641 return true;
1642 }
1643 return false;
1644 };
1645 TraverseWindowTree(func, true);
1646 return isInWindowTree;
1647 }
1648
DumpScreenWindowTreeByWinId(uint32_t winid)1649 void WindowNodeContainer::DumpScreenWindowTreeByWinId(uint32_t winid)
1650 {
1651 WLOGFD("------ dump window info begin -------");
1652 WLOGFD("WindowName WinId Type Mode ZOrd [ x y w h]");
1653 uint32_t zOrder = zOrder_;
1654 WindowNodeOperationFunc func = [&zOrder, &winid](sptr<WindowNode> node) {
1655 Rect rect = node->GetWindowRect();
1656 uint32_t windowId = node->GetWindowId();
1657 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1658 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1659 if (winid == windowId) {
1660 WLOGD("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u "
1661 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1662 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1663 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1664 } else {
1665 WLOGD("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u "
1666 "%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]",
1667 windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1668 --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
1669 }
1670 return false;
1671 };
1672 TraverseWindowTree(func, true);
1673 WLOGFD("------ dump window info end -------");
1674 }
1675
DumpScreenWindowTree()1676 void WindowNodeContainer::DumpScreenWindowTree()
1677 {
1678 WLOGI("------ dump window info begin -------");
1679 WLOGI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation firstFrameCallback [ x y w h]");
1680 uint32_t zOrder = zOrder_;
1681 WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
1682 Rect rect = node->GetWindowRect();
1683 const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
1684 node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
1685 WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u "
1686 "%{public}4u %{public}11u %{public}12d [%{public}4d %{public}4d %{public}4u %{public}4u]",
1687 windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
1688 node->GetWindowFlags(), --zOrder, static_cast<uint32_t>(node->GetRequestedOrientation()),
1689 node->firstFrameAvailable_, rect.posX_, rect.posY_, rect.width_, rect.height_);
1690 return false;
1691 };
1692 TraverseWindowTree(func, true);
1693 WLOGI("------ dump window info end -------");
1694 }
1695
IsVerticalDisplay(DisplayId displayId) const1696 bool WindowNodeContainer::IsVerticalDisplay(DisplayId displayId) const
1697 {
1698 return DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).width_ <
1699 DisplayGroupInfo::GetInstance().GetDisplayRect(displayId).height_;
1700 }
1701
ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)1702 void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason)
1703 {
1704 switch (reason) {
1705 case WindowStateChangeReason::KEYGUARD: {
1706 int32_t topPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD);
1707 TraverseAndUpdateWindowState(state, topPriority);
1708 break;
1709 }
1710 default:
1711 return;
1712 }
1713 }
1714
TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)1715 void WindowNodeContainer::TraverseAndUpdateWindowState(WindowState state, int32_t topPriority)
1716 {
1717 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
1718 for (auto& node : rootNodes) {
1719 UpdateWindowState(node, topPriority, state);
1720 }
1721 }
1722
UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)1723 void WindowNodeContainer::UpdateWindowState(sptr<WindowNode> node, int32_t topPriority, WindowState state)
1724 {
1725 if (node == nullptr) {
1726 return;
1727 }
1728 if (node->parent_ != nullptr && node->currentVisibility_) {
1729 if (node->priority_ < topPriority && !WindowHelper::IsShowWhenLocked(node->GetWindowFlags()) &&
1730 !WindowHelper::IsShowWhenLocked(node->parent_->GetWindowFlags())) {
1731 if (node->GetWindowToken()) {
1732 node->GetWindowToken()->UpdateWindowState(state);
1733 }
1734 HandleKeepScreenOn(node, state);
1735 }
1736 }
1737 for (auto& childNode : node->children_) {
1738 UpdateWindowState(childNode, topPriority, state);
1739 }
1740 }
1741
HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)1742 void WindowNodeContainer::HandleKeepScreenOn(const sptr<WindowNode>& node, WindowState state)
1743 {
1744 if (node == nullptr) {
1745 WLOGFE("window is invalid");
1746 return;
1747 }
1748 if (state == WindowState::STATE_FROZEN) {
1749 HandleKeepScreenOn(node, false);
1750 } else if (state == WindowState::STATE_UNFROZEN) {
1751 HandleKeepScreenOn(node, node->IsKeepScreenOn());
1752 } else {
1753 // do nothing
1754 }
1755 }
1756
FindDividerNode() const1757 sptr<WindowNode> WindowNodeContainer::FindDividerNode() const
1758 {
1759 for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) {
1760 if ((*iter)->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1761 return *iter;
1762 }
1763 }
1764 return nullptr;
1765 }
1766
RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)1767 void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
1768 {
1769 if (node == nullptr) {
1770 return;
1771 }
1772 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
1773 if (windowPair == nullptr) {
1774 WLOGFE("Window pair is nullptr");
1775 return;
1776 }
1777 std::vector<sptr<WindowNode>> orderedPair = windowPair->GetOrderedPair(node);
1778 RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
1779 AssignZOrder();
1780 return;
1781 }
1782
RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)1783 WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode)
1784 {
1785 if (node == nullptr) {
1786 return WMError::WM_ERROR_NULLPTR;
1787 }
1788 if (IsTopWindow(node->GetWindowId(), appWindowNode_) || IsTopWindow(node->GetWindowId(), aboveAppWindowNode_)) {
1789 WLOGE("Window %{public}u is already at top", node->GetWindowId());
1790 return WMError::WM_ERROR_INVALID_TYPE;
1791 }
1792
1793 if (WindowHelper::IsSubWindow(node->GetWindowType()) ||
1794 (node->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1795 if (parentNode == nullptr) {
1796 WLOGFE("window type is invalid");
1797 return WMError::WM_ERROR_NULLPTR;
1798 }
1799 RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself
1800 if (parentNode->IsSplitMode()) {
1801 RaiseSplitRelatedWindowToTop(parentNode);
1802 } else if (parentNode->parent_ != nullptr) {
1803 RaiseWindowToTop(parentNode->GetWindowId(), parentNode->parent_->children_); // raise parent window
1804 }
1805 } else if (WindowHelper::IsMainWindow(node->GetWindowType())) {
1806 if (node->IsSplitMode()) {
1807 RaiseSplitRelatedWindowToTop(node);
1808 } else {
1809 // remote animation continuous start and exit allow parent is nullptr
1810 if (node->parent_ == nullptr) {
1811 WLOGFW("node parent is nullptr");
1812 return WMError::WM_OK;
1813 }
1814 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
1815 }
1816 } else {
1817 // do nothing
1818 }
1819
1820 AssignZOrder();
1821 WLOGI("Raise app window zorder");
1822 DumpScreenWindowTreeByWinId(node->GetWindowId());
1823 return WMError::WM_OK;
1824 }
1825
GetNextFocusableWindow(uint32_t windowId) const1826 sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
1827 {
1828 sptr<WindowNode> nextFocusableWindow;
1829 bool previousFocusedWindowFound = false;
1830 WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
1831 sptr<WindowNode> node) {
1832 if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable() && node->currentVisibility_) {
1833 nextFocusableWindow = node;
1834 return true;
1835 }
1836 if (node->GetWindowId() == windowId) {
1837 previousFocusedWindowFound = true;
1838 }
1839 return false;
1840 };
1841 TraverseWindowTree(func, true);
1842 return nextFocusableWindow;
1843 }
1844
GetNextRotatableWindow(uint32_t windowId) const1845 sptr<WindowNode> WindowNodeContainer::GetNextRotatableWindow(uint32_t windowId) const
1846 {
1847 sptr<WindowNode> nextRotatableWindow;
1848 WindowNodeOperationFunc func = [windowId, &nextRotatableWindow](
1849 sptr<WindowNode> node) {
1850 if (windowId != node->GetWindowId() &&
1851 WindowHelper::IsRotatableWindow(node->GetWindowType(), node->GetWindowMode())) {
1852 nextRotatableWindow = node;
1853 return true;
1854 }
1855 return false;
1856 };
1857 TraverseWindowTree(func, true);
1858 return nextRotatableWindow;
1859 }
1860
GetNextActiveWindow(uint32_t windowId) const1861 sptr<WindowNode> WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) const
1862 {
1863 auto currentNode = FindWindowNodeById(windowId);
1864 if (currentNode == nullptr) {
1865 WLOGFE("cannot find window id: %{public}u by tree", windowId);
1866 return nullptr;
1867 }
1868 WLOGFD("current window: [%{public}u, %{public}u]", windowId, static_cast<uint32_t>(currentNode->GetWindowType()));
1869 if (WindowHelper::IsSystemWindow(currentNode->GetWindowType())) {
1870 for (auto& node : appWindowNode_->children_) {
1871 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
1872 continue;
1873 }
1874 return node;
1875 }
1876 for (auto& node : belowAppWindowNode_->children_) {
1877 if (node->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1878 return node;
1879 }
1880 }
1881 } else if (WindowHelper::IsAppWindow(currentNode->GetWindowType())) {
1882 std::vector<sptr<WindowNode>> windowNodes;
1883 TraverseContainer(windowNodes);
1884 auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), [windowId](sptr<WindowNode>& node) {
1885 return node->GetWindowId() == windowId;
1886 });
1887 if (iter == windowNodes.end()) {
1888 WLOGFE("could not find this window");
1889 return nullptr;
1890 }
1891 int index = std::distance(windowNodes.begin(), iter);
1892 for (size_t i = static_cast<size_t>(index) + 1; i < windowNodes.size(); i++) {
1893 if (windowNodes[i]->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE
1894 || !windowNodes[i]->currentVisibility_) {
1895 continue;
1896 }
1897 return windowNodes[i];
1898 }
1899 } else {
1900 // do nothing
1901 }
1902 WLOGFE("could not get next active window");
1903 return nullptr;
1904 }
1905
IsForbidDockSliceMove(DisplayId displayId) const1906 bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const
1907 {
1908 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1909 if (windowPair == nullptr) {
1910 WLOGFE("window pair is nullptr");
1911 return true;
1912 }
1913 if (windowPair->IsForbidDockSliceMove()) {
1914 return true;
1915 }
1916 return false;
1917 }
1918
IsDockSliceInExitSplitModeArea(DisplayId displayId) const1919 bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const
1920 {
1921 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1922 if (windowPair == nullptr) {
1923 WLOGFE("window pair is nullptr");
1924 return false;
1925 }
1926 std::vector<int32_t> exitSplitPoints = windowPair->GetExitSplitPoints();
1927 if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) {
1928 return false;
1929 }
1930 return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints);
1931 }
1932
ExitSplitMode(DisplayId displayId)1933 void WindowNodeContainer::ExitSplitMode(DisplayId displayId)
1934 {
1935 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
1936 if (windowPair == nullptr) {
1937 WLOGFE("window pair is nullptr");
1938 return;
1939 }
1940 windowPair->ExitSplitMode();
1941 }
1942
MinimizeAllAppWindows(DisplayId displayId)1943 void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId)
1944 {
1945 WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL);
1946 SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId);
1947 if (ret != WMError::WM_OK) {
1948 WLOGFE("Minimize all app window failed");
1949 }
1950 return;
1951 }
1952
GetDeskTopWindow()1953 sptr<WindowNode> WindowNodeContainer::GetDeskTopWindow()
1954 {
1955 sptr<WindowNode> deskTop;
1956 WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr<WindowNode> node) {
1957 if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1958 deskTop = node;
1959 return true;
1960 }
1961 return false;
1962 };
1963 TraverseWindowTree(findDeskTopFunc, false);
1964 return deskTop;
1965 }
1966
HasPrivateWindow()1967 bool WindowNodeContainer::HasPrivateWindow()
1968 {
1969 std::vector<sptr<WindowNode>> windowNodes;
1970 TraverseContainer(windowNodes);
1971 for (const auto& node : windowNodes) {
1972 if (node && node->GetVisibilityState() < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION &&
1973 node->GetWindowProperty()->GetPrivacyMode()) {
1974 WLOGI("window name %{public}s", node->GetWindowName().c_str());
1975 return true;
1976 }
1977 }
1978 return false;
1979 }
1980
HasMainFullScreenWindowShown()1981 bool WindowNodeContainer::HasMainFullScreenWindowShown()
1982 {
1983 std::vector<sptr<WindowNode>> windowNodes;
1984 for (auto& node : appWindowNode_->children_) {
1985 TraverseWindowNode(node, windowNodes);
1986 }
1987 for (const auto& node : windowNodes) {
1988 if (node->currentVisibility_ &&
1989 WindowHelper::IsMainFullScreenWindow(node->GetWindowType(), node->GetWindowMode())) {
1990 return true;
1991 }
1992 }
1993 return false;
1994 }
1995
MinimizeOldestAppWindow()1996 void WindowNodeContainer::MinimizeOldestAppWindow()
1997 {
1998 for (auto& appNode : appWindowNode_->children_) {
1999 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2000 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2001 return;
2002 }
2003 }
2004 for (auto& appNode : aboveAppWindowNode_->children_) {
2005 if (appNode->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2006 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2007 return;
2008 }
2009 }
2010 WLOGD("no window needs to minimize");
2011 }
2012
MinimizeOldestMainFloatingWindow(uint32_t windowId)2013 void WindowNodeContainer::MinimizeOldestMainFloatingWindow(uint32_t windowId)
2014 {
2015 if (maxMainFloatingWindowNumber_ <= 0) {
2016 WLOGD("There is no limit at The number of floating window");
2017 return;
2018 }
2019
2020 auto windowNumber = GetMainFloatingWindowCount();
2021 if (windowNumber <= maxMainFloatingWindowNumber_) {
2022 WLOGD("The number of floating window is less then MaxFloatAppMainWindowNumber");
2023 return;
2024 }
2025 std::vector<sptr<WindowNode>> rootNodes = {
2026 appWindowNode_, aboveAppWindowNode_,
2027 };
2028 for (auto& root : rootNodes) {
2029 for (auto& appNode : root->children_) {
2030 WindowType windowType = appNode->GetWindowType();
2031 WindowMode windowMode = appNode->GetWindowMode();
2032 uint32_t winId = appNode->GetWindowId();
2033 if (windowId != winId && WindowHelper::IsMainFloatingWindow(windowType, windowMode)) {
2034 MinimizeApp::AddNeedMinimizeApp(appNode, MinimizeReason::MAX_APP_COUNT);
2035 return;
2036 }
2037 }
2038 }
2039 WLOGD("no window needs to minimize");
2040 }
2041
ToggleShownStateForAllAppWindows( std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)2042 WMError WindowNodeContainer::ToggleShownStateForAllAppWindows(
2043 std::function<bool(uint32_t, WindowMode)> restoreFunc, bool restore)
2044 {
2045 for (auto node : aboveAppWindowNode_->children_) {
2046 if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT &&
2047 node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && restore) {
2048 return WMError::WM_DO_NOTHING;
2049 }
2050 }
2051 // to do, backup reentry: 1.ToggleShownStateForAllAppWindows fast; 2.this display should reset backupWindowIds_.
2052 if (!restore && appWindowNode_->children_.empty() && !backupWindowIds_.empty()) {
2053 backupWindowIds_.clear();
2054 backupWindowMode_.clear();
2055 backupDisplaySplitWindowMode_.clear();
2056 backupDividerWindowRect_.clear();
2057 }
2058 if (!restore && !appWindowNode_->children_.empty() && backupWindowIds_.empty()) {
2059 WLOGD("backup");
2060 BackUpAllAppWindows();
2061 } else if (restore && !backupWindowIds_.empty()) {
2062 WLOGD("restore");
2063 RestoreAllAppWindows(restoreFunc);
2064 } else {
2065 WLOGD("do nothing because shown app windows is empty or backup windows is empty.");
2066 }
2067 WLOGD("ToggleShownStateForAllAppWindows");
2068 return WMError::WM_OK;
2069 }
2070
BackUpAllAppWindows()2071 void WindowNodeContainer::BackUpAllAppWindows()
2072 {
2073 std::set<DisplayId> displayIdSet;
2074 backupWindowMode_.clear();
2075 backupDisplaySplitWindowMode_.clear();
2076 std::vector<sptr<WindowNode>> children = appWindowNode_->children_;
2077 for (auto& appNode : children) {
2078 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2079 continue;
2080 }
2081 auto windowMode = appNode->GetWindowMode();
2082 backupWindowMode_[appNode->GetWindowId()] = windowMode;
2083 if (WindowHelper::IsSplitWindowMode(windowMode)) {
2084 backupDisplaySplitWindowMode_[appNode->GetDisplayId()].insert(windowMode);
2085 }
2086 displayIdSet.insert(appNode->GetDisplayId());
2087 }
2088 for (auto& appNode : children) {
2089 // exclude exceptional window
2090 if (!WindowHelper::IsMainWindow(appNode->GetWindowType())) {
2091 WLOGFE("is not main window, windowId:%{public}u", appNode->GetWindowId());
2092 continue;
2093 }
2094 // minimize window
2095 WLOGFD("minimize window, windowId:%{public}u", appNode->GetWindowId());
2096 backupWindowIds_.emplace_back(appNode->GetWindowId());
2097 WindowManagerService::GetInstance().RemoveWindow(appNode->GetWindowId(), true);
2098 wptr<IRemoteObject> abilityToken = appNode->abilityToken_;
2099 auto task = [abilityToken]() {
2100 auto token = abilityToken.promote();
2101 if (token == nullptr) {
2102 WLOGFW("Ability token is null");
2103 return;
2104 }
2105 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(token,
2106 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
2107 };
2108 WindowInnerManager::GetInstance().PostTask(task, "DoAbilityBackground");
2109 }
2110 backupDividerWindowRect_.clear();
2111 for (auto displayId : displayIdSet) {
2112 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2113 if (windowPair == nullptr || windowPair->GetDividerWindow() == nullptr) {
2114 continue;
2115 }
2116 backupDividerWindowRect_[displayId] = windowPair->GetDividerWindow()->GetWindowRect();
2117 }
2118 }
2119
RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)2120 void WindowNodeContainer::RestoreAllAppWindows(std::function<bool(uint32_t, WindowMode)> restoreFunc)
2121 {
2122 std::vector<uint32_t> backupWindowIds(backupWindowIds_);
2123 auto displayIds = DisplayGroupInfo::GetInstance().GetAllDisplayIds();
2124 std::vector<sptr<WindowPair>> windowPairs;
2125 for (auto displayId : displayIds) {
2126 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2127 if (windowPair != nullptr) {
2128 if (backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_PRIMARY) > 0 &&
2129 backupDisplaySplitWindowMode_[displayId].count(WindowMode::WINDOW_MODE_SPLIT_SECONDARY) > 0) {
2130 windowPair->SetAllSplitAppWindowsRestoring(true);
2131 }
2132 windowPairs.emplace_back(windowPair);
2133 }
2134 }
2135 for (auto windowId: backupWindowIds) {
2136 if (!restoreFunc(windowId, backupWindowMode_[windowId])) {
2137 WLOGFE("restore %{public}u failed", windowId);
2138 continue;
2139 }
2140 WLOGFD("restore %{public}u", windowId);
2141 }
2142 for (auto windowPair : windowPairs) {
2143 windowPair->SetAllSplitAppWindowsRestoring(false);
2144 }
2145 layoutPolicy_->SetSplitDividerWindowRects(backupDividerWindowRect_);
2146 backupWindowIds_.clear();
2147 backupWindowMode_.clear();
2148 backupDividerWindowRect_.clear();
2149 }
2150
IsAppWindowsEmpty() const2151 bool WindowNodeContainer::IsAppWindowsEmpty() const
2152 {
2153 return appWindowNode_->children_.empty();
2154 }
2155
MinimizeAppNodeExceptOptions(MinimizeReason reason, const std::vector<uint32_t>& exceptionalIds, const std::vector<WindowMode>& exceptionalModes)2156 WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(MinimizeReason reason,
2157 const std::vector<uint32_t>& exceptionalIds, const std::vector<WindowMode>& exceptionalModes)
2158 {
2159 if (appWindowNode_->children_.empty()) {
2160 return WMError::WM_OK;
2161 }
2162 for (auto& appNode : appWindowNode_->children_) {
2163 // exclude exceptional window
2164 if (std::find(exceptionalIds.begin(), exceptionalIds.end(), appNode->GetWindowId()) != exceptionalIds.end() ||
2165 std::find(exceptionalModes.begin(), exceptionalModes.end(),
2166 appNode->GetWindowMode()) != exceptionalModes.end() ||
2167 appNode->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2168 continue;
2169 }
2170 MinimizeApp::AddNeedMinimizeApp(appNode, reason);
2171 }
2172 return WMError::WM_OK;
2173 }
2174
MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)2175 WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr<WindowNode>& node)
2176 {
2177 std::vector<uint32_t> exceptionalIds = { node->GetWindowId() };
2178 std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
2179 return MinimizeAppNodeExceptOptions(MinimizeReason::OTHER_WINDOW, exceptionalIds, exceptionalModes);
2180 }
2181
SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)2182 WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder)
2183 {
2184 WLOGD("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"",
2185 static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder), displayId);
2186 if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) {
2187 WLOGFE("invalid layout mode");
2188 return WMError::WM_ERROR_INVALID_PARAM;
2189 }
2190 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2191 if (windowPair == nullptr) {
2192 WLOGFE("Window pair is nullptr");
2193 return WMError::WM_ERROR_NULLPTR;
2194 }
2195 if (layoutMode_ != dstMode) {
2196 if (layoutMode_ == WindowLayoutMode::CASCADE) {
2197 windowPair->Clear();
2198 }
2199 layoutMode_ = dstMode;
2200 layoutPolicy_ = layoutPolicies_[dstMode];
2201 layoutPolicy_->Launch();
2202 DumpScreenWindowTree();
2203 } else {
2204 WLOGI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
2205 }
2206 if (reorder) {
2207 windowPair->Clear();
2208 layoutPolicy_->Reorder();
2209 DumpScreenWindowTree();
2210 }
2211 NotifyIfSystemBarTintChanged(displayId);
2212 NotifyDockWindowStateChanged(displayId);
2213 return WMError::WM_OK;
2214 }
2215
UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)2216 void WindowNodeContainer::UpdateModeSupportInfoWhenKeyguardChange(const sptr<WindowNode>& node, bool up)
2217 {
2218 if (!WindowHelper::IsWindowModeSupported(node->GetWindowProperty()->GetRequestModeSupportInfo(),
2219 WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2220 WLOGFD("window doesn't support split mode, winId: %{public}d", node->GetWindowId());
2221 return;
2222 }
2223 uint32_t modeSupportInfo;
2224 if (up) {
2225 modeSupportInfo = node->GetModeSupportInfo() & (~WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
2226 } else {
2227 modeSupportInfo = node->GetModeSupportInfo() | WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY;
2228 }
2229 node->SetModeSupportInfo(modeSupportInfo);
2230 if (node->GetWindowToken() != nullptr) {
2231 node->GetWindowToken()->UpdateWindowModeSupportInfo(modeSupportInfo);
2232 }
2233 }
2234
RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const2235 void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const
2236 {
2237 if (node->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2238 return;
2239 }
2240
2241 if (isScreenLocked_) {
2242 node->priority_ = zorderPolicy_->GetWindowPriority(
2243 WindowType::WINDOW_TYPE_KEYGUARD) + 2; // 2: higher than keyguard and show when locked window
2244 WLOGD("Raise input method float window priority when screen locked.");
2245 return;
2246 }
2247
2248 auto callingWindowId = node->GetCallingWindow();
2249 auto callingWindow = FindWindowNodeById(callingWindowId);
2250 if (callingWindowId == focusedWindow_ && callingWindow != nullptr) {
2251 auto callingWindowType = callingWindow->GetWindowType();
2252 auto callingWindowPriority = zorderPolicy_->GetWindowPriority(callingWindowType);
2253 auto inputMethodPriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2254
2255 node->priority_ = (inputMethodPriority < callingWindowPriority) ?
2256 (callingWindowPriority + 1) : inputMethodPriority;
2257 WLOGFD("Reset input method float window priority to %{public}d.", node->priority_);
2258 return;
2259 }
2260
2261 auto focusWindow = FindWindowNodeById(focusedWindow_);
2262 if (focusWindow != nullptr && focusWindow->GetWindowType() == WindowType::WINDOW_TYPE_PANEL) {
2263 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_PANEL) + 1;
2264 WLOGFD("The input method float window should be higher than panel");
2265 }
2266 }
2267
ReZOrderShowWhenLockedWindows(bool up)2268 void WindowNodeContainer::ReZOrderShowWhenLockedWindows(bool up)
2269 {
2270 WLOGD("Keyguard change %{public}u, re-zorder showWhenLocked window", up);
2271 std::vector<sptr<WindowNode>> needReZOrderNodes;
2272 auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_;
2273 auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_;
2274
2275 auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 :
2276 zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
2277
2278 for (auto iter = srcRoot->children_.begin(); iter != srcRoot->children_.end();) {
2279 if ((*iter)->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
2280 needReZOrderNodes.emplace_back(*iter);
2281 iter = srcRoot->children_.erase(iter);
2282 } else {
2283 iter++;
2284 }
2285 }
2286 const int32_t floatingPriorityOffset = 1;
2287 for (auto& needReZOrderNode : needReZOrderNodes) {
2288 needReZOrderNode->priority_ = dstPriority;
2289 needReZOrderNode->parent_ = dstRoot;
2290 if (WindowHelper::IsMainFloatingWindow(needReZOrderNode->GetWindowType(),
2291 needReZOrderNode->GetWindowMode()) && isFloatWindowAboveFullWindow_) {
2292 needReZOrderNode->priority_ = dstPriority + floatingPriorityOffset;
2293 }
2294 auto parentNode = needReZOrderNode->parent_;
2295 auto position = parentNode->children_.end();
2296 for (auto iter = parentNode->children_.begin(); iter < parentNode->children_.end(); ++iter) {
2297 if ((*iter)->priority_ > needReZOrderNode->priority_) {
2298 position = iter;
2299 break;
2300 }
2301 }
2302
2303 UpdateModeSupportInfoWhenKeyguardChange(needReZOrderNode, up);
2304
2305 parentNode->children_.insert(position, needReZOrderNode);
2306 if (up && WindowHelper::IsSplitWindowMode(needReZOrderNode->GetWindowMode())) {
2307 needReZOrderNode->GetWindowProperty()->ResumeLastWindowMode();
2308 // when change mode, need to reset shadow and radius
2309 WindowSystemEffect::SetWindowEffect(needReZOrderNode);
2310 if (needReZOrderNode->GetWindowToken() != nullptr) {
2311 needReZOrderNode->GetWindowToken()->UpdateWindowMode(needReZOrderNode->GetWindowMode());
2312 }
2313 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(needReZOrderNode->GetDisplayId());
2314 if (windowPair == nullptr) {
2315 WLOGFE("Window pair is nullptr");
2316 return;
2317 }
2318 windowPair->UpdateIfSplitRelated(needReZOrderNode);
2319 }
2320 WLOGD("window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up);
2321 }
2322 }
2323
ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)2324 void WindowNodeContainer::ReZOrderShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2325 {
2326 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2327 !isScreenLocked_) {
2328 return;
2329 }
2330
2331 ReZOrderShowWhenLockedWindows(true);
2332 WLOGI("ShowWhenLocked window %{public}u re-zorder to up", node->GetWindowId());
2333 }
2334
RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)2335 void WindowNodeContainer::RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2336 {
2337 // if keyguard window show, raise show when locked windows
2338 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2339 ReZOrderShowWhenLockedWindows(true);
2340 return;
2341 }
2342
2343 // if show when locked window show, raise itself when exist keyguard
2344 if (!(node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) ||
2345 !isScreenLocked_) {
2346 return;
2347 }
2348
2349 node->priority_ = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2350 node->parent_ = aboveAppWindowNode_;
2351 if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) {
2352 node->GetWindowProperty()->ResumeLastWindowMode();
2353 // when change mode, need to reset shadow and radius
2354 WindowSystemEffect::SetWindowEffect(node);
2355 if (node->GetWindowToken() != nullptr) {
2356 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2357 }
2358 }
2359 WLOGI("ShowWhenLocked window %{public}u raise itself", node->GetWindowId());
2360 }
2361
DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)2362 void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node)
2363 {
2364 // if keyguard window hide, drop show when locked windows
2365 if (node->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) {
2366 ReZOrderShowWhenLockedWindows(false);
2367 AssignZOrder();
2368 }
2369 }
2370
TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const2371 void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
2372 {
2373 std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
2374 if (isFromTopToBottom) {
2375 std::reverse(rootNodes.begin(), rootNodes.end());
2376 }
2377
2378 for (const auto& node : rootNodes) {
2379 if (isFromTopToBottom) {
2380 for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
2381 if (TraverseFromTopToBottom(*iter, func)) {
2382 return;
2383 }
2384 }
2385 } else {
2386 for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
2387 if (TraverseFromBottomToTop(*iter, func)) {
2388 return;
2389 }
2390 }
2391 }
2392 }
2393 }
2394
TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const2395 bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2396 {
2397 if (node == nullptr) {
2398 return false;
2399 }
2400 auto iterBegin = node->children_.rbegin();
2401 for (; iterBegin != node->children_.rend(); ++iterBegin) {
2402 if ((*iterBegin)->priority_ <= 0) {
2403 break;
2404 }
2405 if (func(*iterBegin)) {
2406 return true;
2407 }
2408 }
2409 if (func(node)) {
2410 return true;
2411 }
2412 for (; iterBegin != node->children_.rend(); ++iterBegin) {
2413 if (func(*iterBegin)) {
2414 return true;
2415 }
2416 }
2417 return false;
2418 }
2419
TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const2420 bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
2421 {
2422 if (node == nullptr) {
2423 return false;
2424 }
2425 auto iterBegin = node->children_.begin();
2426 for (; iterBegin != node->children_.end(); ++iterBegin) {
2427 if ((*iterBegin)->priority_ >= 0) {
2428 break;
2429 }
2430 if (func(*iterBegin)) {
2431 return true;
2432 }
2433 }
2434 if (func(node)) {
2435 return true;
2436 }
2437 for (; iterBegin != node->children_.end(); ++iterBegin) {
2438 if (func(*iterBegin)) {
2439 return true;
2440 }
2441 }
2442 return false;
2443 }
2444
GetDisplayGroupRect() const2445 Rect WindowNodeContainer::GetDisplayGroupRect() const
2446 {
2447 return layoutPolicy_->GetDisplayGroupRect();
2448 }
2449
UpdateSizeChangeReason(sptr<WindowNode>& node, WindowMode srcMode, WindowMode dstMode)2450 void WindowNodeContainer::UpdateSizeChangeReason(sptr<WindowNode>& node, WindowMode srcMode, WindowMode dstMode)
2451 {
2452 if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
2453 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
2454 } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2455 node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
2456 if (srcMode == WindowMode::WINDOW_MODE_FLOATING) {
2457 node->SetRequestRect(node->GetWindowRect());
2458 }
2459 } else if (WindowHelper::IsFullScreenWindow(srcMode) && WindowHelper::IsSplitWindowMode(dstMode)) {
2460 node->SetWindowSizeChangeReason(WindowSizeChangeReason::FULL_TO_SPLIT);
2461 } else if (WindowHelper::IsSplitWindowMode(srcMode) && WindowHelper::IsFullScreenWindow(dstMode)) {
2462 node->SetWindowSizeChangeReason(WindowSizeChangeReason::SPLIT_TO_FULL);
2463 } else {
2464 node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
2465 }
2466 }
2467
SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)2468 WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
2469 {
2470 if (node == nullptr) {
2471 WLOGFE("could not find window");
2472 return WMError::WM_ERROR_NULLPTR;
2473 }
2474 WindowMode srcMode = node->GetWindowMode();
2475 if (WindowHelper::IsSplitWindowMode(dstMode) && isScreenLocked_ &&
2476 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2477 return WMError::WM_ERROR_INVALID_PARAM;
2478 }
2479
2480 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(node->GetDisplayId());
2481 if (windowPair == nullptr) {
2482 WLOGFE("Window pair is nullptr");
2483 return WMError::WM_ERROR_NULLPTR;
2484 }
2485
2486 WindowPairStatus status = windowPair->GetPairStatus();
2487 // when status is single primary or single secondary, split node is abandoned to set mode
2488 if (node->IsSplitMode() && (status == WindowPairStatus::SINGLE_PRIMARY ||
2489 status == WindowPairStatus::SINGLE_SECONDARY)) {
2490 return WMError::WM_ERROR_INVALID_OPERATION;
2491 }
2492 WMError res = WMError::WM_OK;
2493 UpdateSizeChangeReason(node, srcMode, dstMode);
2494 node->SetWindowMode(dstMode);
2495 windowPair->UpdateIfSplitRelated(node);
2496
2497 if (WindowHelper::IsMainWindow(node->GetWindowType())) {
2498 if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) {
2499 NotifyDockWindowStateChanged(node, true);
2500 } else {
2501 NotifyDockWindowStateChanged(node, false);
2502 }
2503 }
2504
2505 if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2506 WindowHelper::IsAppWindow(node->GetWindowType())) {
2507 // minimize other app window.
2508 res = MinimizeStructuredAppWindowsExceptSelf(node);
2509 if (res != WMError::WM_OK) {
2510 return res;
2511 }
2512 }
2513 // when change mode, need to reset shadow and radius.
2514 WindowSystemEffect::SetWindowEffect(node);
2515
2516 // when change mode, need to reset MainFloatingWindow ZOrder.
2517 ResetWindowZOrderPriorityWhenSetMode(node, dstMode, srcMode);
2518 MinimizeOldestMainFloatingWindow(node->GetWindowId());
2519
2520 if (node->GetWindowToken() != nullptr) {
2521 node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
2522 }
2523 res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
2524 if (res != WMError::WM_OK) {
2525 WLOGFE("Set window mode failed, update node failed");
2526 return res;
2527 }
2528 return WMError::WM_OK;
2529 }
2530
ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode>& node, const WindowMode& dstMode, const WindowMode& srcMode)2531 void WindowNodeContainer::ResetWindowZOrderPriorityWhenSetMode(sptr<WindowNode>& node,
2532 const WindowMode& dstMode, const WindowMode& srcMode)
2533 {
2534 if (!isFloatWindowAboveFullWindow_) {
2535 return;
2536 }
2537
2538 // reset node zorder priority.
2539 if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode)) {
2540 auto basePriority = zorderPolicy_->GetWindowPriority(node->GetWindowType());
2541 if (isScreenLocked_ &&
2542 (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))) {
2543 basePriority = zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1;
2544 }
2545 node->priority_ = basePriority;
2546 }
2547
2548 if (!WindowHelper::IsMainFloatingWindow(node->GetWindowType(), srcMode) &&
2549 !WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode) &&
2550 !WindowHelper::IsSplitWindowMode(srcMode) &&
2551 !WindowHelper::IsSplitWindowMode(dstMode)) {
2552 return;
2553 }
2554
2555 // When set mode, all floating window should be checked and raise
2556 ResetAllMainFloatingWindowZOrder(node->parent_);
2557 if (node->parent_ != nullptr && node->GetWindowId() == focusedWindow_ &&
2558 WindowHelper::IsMainFloatingWindow(node->GetWindowType(), dstMode)) {
2559 // if current node is mainFloatingWIndow and foucsedWindow, it should be raised to top.
2560 RaiseWindowToTop(node->GetWindowId(), node->parent_->children_);
2561 }
2562 AssignZOrder();
2563 }
2564
GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config)2565 void WindowNodeContainer::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones,
2566 const ModeChangeHotZonesConfig& config)
2567 {
2568 const auto& displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
2569
2570 hotZones.fullscreen_.width_ = displayRect.width_;
2571 hotZones.fullscreen_.height_ = config.fullscreenRange_;
2572
2573 hotZones.primary_.width_ = config.primaryRange_;
2574 hotZones.primary_.height_ = displayRect.height_;
2575
2576 hotZones.secondary_.posX_ = static_cast<int32_t>(displayRect.width_) - config.secondaryRange_;
2577 hotZones.secondary_.width_ = config.secondaryRange_;
2578 hotZones.secondary_.height_ = displayRect.height_;
2579 }
2580
UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)2581 void WindowNodeContainer::UpdateCameraFloatWindowStatus(const sptr<WindowNode>& node, bool isShowing)
2582 {
2583 if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2584 WindowManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(node->GetAccessTokenId(), isShowing);
2585 }
2586 }
2587
GetCurrentLayoutMode() const2588 WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
2589 {
2590 return layoutMode_;
2591 }
2592
RemoveSingleUserWindowNodes(int accountId)2593 void WindowNodeContainer::RemoveSingleUserWindowNodes(int accountId)
2594 {
2595 std::vector<sptr<WindowNode>> windowNodes;
2596 TraverseContainer(windowNodes);
2597 WLOGI("%{public}d", accountId);
2598 for (auto& windowNode : windowNodes) {
2599 int windowAccountId = windowNode->GetCallingUid() / UID_TRANSFROM_DIVISOR;
2600 if (windowAccountId < UID_MIN || windowAccountId == accountId) {
2601 WLOGD("skiped window %{public}s, windowId %{public}d uid %{public}d",
2602 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2603 continue;
2604 }
2605 WLOGD("remove window %{public}s, windowId %{public}d uid %{public}d",
2606 windowNode->GetWindowName().c_str(), windowNode->GetWindowId(), windowNode->GetCallingUid());
2607 windowNode->GetWindowProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
2608 if (windowNode->GetWindowToken()) {
2609 if (windowNode->surfaceNode_ != nullptr) {
2610 windowNode->surfaceNode_->SetVisible(true);
2611 }
2612 windowNode->GetWindowToken()->UpdateWindowState(WindowState::STATE_HIDDEN);
2613 }
2614 }
2615 }
2616
TakeWindowPairSnapshot(DisplayId displayId)2617 bool WindowNodeContainer::TakeWindowPairSnapshot(DisplayId displayId)
2618 {
2619 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2620 return windowPair == nullptr ? false : windowPair->TakePairSnapshot();
2621 }
2622
ClearWindowPairSnapshot(DisplayId displayId)2623 void WindowNodeContainer::ClearWindowPairSnapshot(DisplayId displayId)
2624 {
2625 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2626 if (windowPair == nullptr) {
2627 WLOGFE("Window pair is nullptr");
2628 return;
2629 }
2630 windowPair->ClearPairSnapshot();
2631 }
2632
SetWindowPairFrameGravity(DisplayId displayId, Gravity gravity)2633 void WindowNodeContainer::SetWindowPairFrameGravity(DisplayId displayId, Gravity gravity)
2634 {
2635 auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId);
2636 if (windowPair == nullptr) {
2637 WLOGFE("Window pair is nullptr");
2638 return;
2639 }
2640 std::vector<sptr<WindowNode>> windowNodes = windowPair->GetPairedWindows();
2641 for (auto& windowNode : windowNodes) {
2642 if (windowNode->surfaceNode_) {
2643 windowNode->surfaceNode_->SetFrameGravity(gravity);
2644 }
2645 }
2646 }
2647
IsScreenLocked()2648 bool WindowNodeContainer::IsScreenLocked()
2649 {
2650 return isScreenLocked_;
2651 }
2652
GetAnimateTransactionEnabled()2653 bool WindowNodeContainer::GetAnimateTransactionEnabled()
2654 {
2655 return isAnimateTransactionEnabled_;
2656 }
2657 } // namespace Rosen
2658 } // namespace OHOS
2659