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