1 /*
2  * Copyright (c) 2024 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 #include "window_scene_layout_manager.h"
16 
17 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
18 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
19 #include "core/components_ng/pattern/window_scene/scene/window_scene.h"
20 #include "core/components_ng/pattern/window_scene/scene/panel_scene.h"
21 #include "core/components_ng/pattern/window_scene/scene/input_scene.h"
22 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
23 #include "core/components_ng/pattern/window_scene/screen/screen_pattern.h"
24 #include "core/components_ng/render/adapter/rosen_render_context.h"
25 #include "core/pipeline_ng/pipeline_context.h"
26 #include "parameters.h"
27 #include "session/host/include/session.h"
28 #include "session_manager/include/scene_session_manager.h"
29 
30 namespace {
31 constexpr uint64_t SCREEN_ID_INVALID = -1ULL;
32 constexpr float EPSILON = 1e-3;
33 }
34 namespace OHOS::Ace::NG {
GetInstance()35 WindowSceneLayoutManager* WindowSceneLayoutManager::GetInstance()
36 {
37     auto container = Container::Current();
38     if (!container || !container->IsScenceBoardWindow() || !Rosen::Session::IsScbCoreEnabled()) {
39         return nullptr;
40     }
41     static WindowSceneLayoutManager* instance = nullptr;
42     if (instance == nullptr) {
43         instance = new WindowSceneLayoutManager();
44         instance->Init();
45     }
46     return instance;
47 }
48 
Init()49 void WindowSceneLayoutManager::Init()
50 {
51     Rosen::SceneSessionManager::GetInstance().SetDumpUITreeFunc(
52         [this](std::string& info) {
53             isCoreDebugEnable_ = system::GetParameter("debug.window.coredebug.enabled", "0") == "1";
54             GetTotalUITreeInfo(info);
55         }
56     );
57 }
58 
IsNodeDirty(const RefPtr<FrameNode> & node)59 bool WindowSceneLayoutManager::IsNodeDirty(const RefPtr<FrameNode>& node)
60 {
61     auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
62     CHECK_NULL_RETURN(context, false);
63     auto rsNode = context->GetRSNode();
64     CHECK_NULL_RETURN(rsNode, false);
65     return rsNode->IsAppearanceDirty() || rsNode->IsGeometryDirty();
66 }
67 
IsNodeVisible(const RefPtr<FrameNode> & node)68 bool WindowSceneLayoutManager::IsNodeVisible(const RefPtr<FrameNode>& node)
69 {
70     CHECK_NULL_RETURN(node, false);
71     auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
72     CHECK_NULL_RETURN(context, false);
73     auto rsNode = context->GetRSNode();
74     CHECK_NULL_RETURN(rsNode, false);
75     bool isVisible = node->IsVisible();
76     float opacityVal = context->GetOpacityValue(1.0f);
77     bool opaque = (opacityVal - 0.0f) > std::numeric_limits<float>::epsilon();
78     bool ret = isVisible && opaque;
79     if (isCoreDebugEnable_) {
80         TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "winId:%{public}d name:%{public}s frameNodeId:%{public}d"
81             "isVisible:%{public}d opaque:%{public}f ret:%{public}d", GetWindowId(node),
82             GetWindowName(node).c_str(), node->GetId(), isVisible, opacityVal, ret);
83     }
84     return ret;
85 }
86 
GetNodeZIndex(const RefPtr<FrameNode> & node)87 int32_t WindowSceneLayoutManager::GetNodeZIndex(const RefPtr<FrameNode>& node)
88 {
89     CHECK_NULL_RETURN(node, ZINDEX_DEFAULT_VALUE);
90     auto context = node->GetRenderContext();
91     CHECK_NULL_RETURN(context, ZINDEX_DEFAULT_VALUE);
92     return context->GetZIndexValue(ZINDEX_DEFAULT_VALUE);
93 }
94 
GetScreenId(const RefPtr<FrameNode> & screenNode)95 uint64_t WindowSceneLayoutManager::GetScreenId(const RefPtr<FrameNode>& screenNode)
96 {
97     CHECK_NULL_RETURN(screenNode, SCREEN_ID_INVALID);
98     auto pattern = screenNode->GetPattern<ScreenPattern>();
99     CHECK_NULL_RETURN(pattern, SCREEN_ID_INVALID);
100     auto screenSession = pattern->GetScreenSession();
101     CHECK_NULL_RETURN(screenSession, SCREEN_ID_INVALID);
102     return screenSession->GetScreenId();
103 }
104 
UpdateGeometry(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & parentNode,bool isParentTransformScene)105 void WindowSceneLayoutManager::UpdateGeometry(const RefPtr<FrameNode>& node, const RefPtr<FrameNode>& parentNode,
106     bool isParentTransformScene)
107 {
108     CHECK_NULL_VOID(node);
109     auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
110     CHECK_NULL_VOID(context);
111     auto rsNode = context->GetRSNode();
112     CHECK_NULL_VOID(rsNode);
113     auto globalGeometry = isParentTransformScene ? std::make_shared<Rosen::RSObjAbsGeometry>()
114         : GetGlobalGeometry(parentNode);
115     if (!globalGeometry) {
116         if (!WindowSceneHelper::IsScreenScene(node->GetWindowPatternType())) {
117             TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE, "windowName:%{public}s, global geo is null and new",
118                 GetWindowName(node).c_str());
119         }
120         globalGeometry = std::make_shared<Rosen::RSObjAbsGeometry>();
121     }
122     rsNode->UpdateLocalGeometry();
123     if (WindowSceneHelper::IsTransformScene(node->GetWindowPatternType())) {
124         // once current transform scene, set pos/trans 0, to make global position relative to transform scene
125         if (auto localGeo = rsNode->GetLocalGeometry()) {
126             localGeo->SetPosition(0.0f, 0.0f);
127             localGeo->SetTranslateX(0.0f);
128             localGeo->SetTranslateY(0.0f);
129         } else {
130             TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE, "windowName:%{public}s, local geo is null",
131                 GetWindowName(node).c_str());
132         }
133     }
134     rsNode->UpdateGlobalGeometry(globalGeometry);
135     rsNode->MarkDirty(Rosen::NodeDirtyType::GEOMETRY, false);
136     rsNode->MarkDirty(Rosen::NodeDirtyType::APPEARANCE, false);
137     DumpNodeInfo(node, parentNode, "UpdateGeometry");
138 }
139 
GetRSNode(const RefPtr<FrameNode> & node)140 std::shared_ptr<Rosen::RSNode> WindowSceneLayoutManager::GetRSNode(const RefPtr<FrameNode>& node)
141 {
142     CHECK_NULL_RETURN(node, nullptr);
143     auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
144     CHECK_NULL_RETURN(context, nullptr);
145     return context->GetRSNode();
146 }
147 
GetGlobalGeometry(const RefPtr<FrameNode> & node)148 std::shared_ptr<Rosen::RSObjAbsGeometry> WindowSceneLayoutManager::GetGlobalGeometry(const RefPtr<FrameNode>& node)
149 {
150     auto rsNode = GetRSNode(node);
151     CHECK_NULL_RETURN(rsNode, nullptr);
152     return rsNode->GetGlobalGeometry();
153 }
154 
GetLocalGeometry(const RefPtr<FrameNode> & node)155 std::shared_ptr<Rosen::RSObjAbsGeometry> WindowSceneLayoutManager::GetLocalGeometry(const RefPtr<FrameNode>& node)
156 {
157     auto rsNode = GetRSNode(node);
158     CHECK_NULL_RETURN(rsNode, nullptr);
159     return rsNode->GetLocalGeometry();
160 }
161 
FillWindowSceneInfo(const RefPtr<FrameNode> & node,TraverseResult & res,bool isAncestorRecent,bool notSyncPosition)162 void WindowSceneLayoutManager::FillWindowSceneInfo(const RefPtr<FrameNode>& node,
163     TraverseResult& res, bool isAncestorRecent, bool notSyncPosition)
164 {
165     auto rsNode = GetRSNode(node);
166     if (!rsNode) {
167         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s rsNode is null", GetWindowName(node).c_str());
168         return;
169     }
170     IsFrameNodeAbnormal(node);
171     auto globalGeometry = isAncestorRecent ? std::make_shared<Rosen::RSObjAbsGeometry>()
172                                            : rsNode->GetGlobalGeometry();
173     auto localGeometry = rsNode->GetLocalGeometry();
174     if (isAncestorRecent && !localGeometry) {
175         localGeometry = std::make_shared<Rosen::RSObjAbsGeometry>();
176     }
177     if (!globalGeometry || !localGeometry) {
178         if (isCoreDebugEnable_) {
179             TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s globalGeo is null:%{public}d localGeo:%{public}d",
180                 GetWindowName(node).c_str(), globalGeometry == nullptr, localGeometry == nullptr);
181         }
182         return;
183     }
184     Rosen::SessionUIParam uiParam;
185     auto width = localGeometry->GetWidth();
186     auto height = localGeometry->GetHeight();
187     if (std::abs(width - 0.0f) < EPSILON || std::abs(height - 0.0f) < EPSILON) {
188         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s w:%{public}f h:%{public}f is 0",
189             GetWindowName(node).c_str(), width, height);
190         return;
191     }
192     if (isAncestorRecent) {
193         uiParam.rect_ = { localGeometry->GetX(), localGeometry->GetY(), width, height };
194     } else {
195         auto absRect = globalGeometry->GetAbsRect();
196         uiParam.rect_ = { absRect.GetLeft(), absRect.GetTop(), width, height };
197         uiParam.scaleX_ = absRect.GetWidth() / width;
198         uiParam.scaleY_ = absRect.GetHeight() / height;
199     }
200     uiParam.needSync_ = notSyncPosition ? false : true;
201     auto matrix = globalGeometry->GetAbsMatrix();
202     uiParam.transX_ = std::round(matrix.Get(Rosen::Drawing::Matrix::TRANS_X) - rsNode->GetGlobalPositionX());
203     uiParam.transY_ = std::round(matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) - rsNode->GetGlobalPositionY());
204     uiParam.pivotX_ = globalGeometry->GetPivotX();
205     uiParam.pivotY_ = globalGeometry->GetPivotY();
206     uiParam.zOrder_ = res.zOrderCnt_;
207     auto windowId = GetWindowId(node);
208     uiParam.sessionName_ = GetWindowName(node);
209     if (isAncestorRecent) {
210         // panel scene self should be interactive, others should be false
211         // default interactive is true
212         uiParam.interactive_ = WindowSceneHelper::IsPanelScene(node->GetWindowPatternType());
213     }
214     res.uiParams_[windowId] = std::move(uiParam);
215 }
216 
FlushWindowPatternInfo(const RefPtr<FrameNode> & screenNode)217 void WindowSceneLayoutManager::FlushWindowPatternInfo(const RefPtr<FrameNode>& screenNode)
218 {
219     if (isCoreDebugEnable_) {
220         TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "------------------- Begin FlushWindowPatternInfo ------------------");
221     }
222     auto screenId = GetScreenId(screenNode);
223     if (screenId == SCREEN_ID_INVALID) {
224         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE,
225             "tag:%{public}s screenId:%{public}" PRIu64, screenNode->GetTag().c_str(), screenId);
226         return;
227     }
228     TraverseResult res;
229     res.zOrderCnt_ = 0;
230     res.screenId_ = screenId;
231     UpdateGeometry(screenNode, nullptr, false);
232     TraverseTree(screenNode, res, false, IsNodeDirty(screenNode), false);
233     if (isCoreDebugEnable_) {
234         DumpFlushInfo(screenId, res);
235         TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "------------------- End FlushWindowPatternInfo ------------------");
236     }
237     // cannot post ui task, since flush may not excute on next frame
238     Rosen::SceneSessionManager::GetInstance().FlushUIParams(screenId, std::move(res.uiParams_));
239 }
240 
IsRecentContainerState(const RefPtr<FrameNode> & node)241 bool WindowSceneLayoutManager::IsRecentContainerState(const RefPtr<FrameNode>& node)
242 {
243     CHECK_NULL_RETURN(node, false);
244     if (!WindowSceneHelper::IsPanelScene(node->GetWindowPatternType())) {
245         return false;
246     }
247     auto windowPattern = node->GetPattern<PanelScene>();
248     if (windowPattern == nullptr) {
249         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent SystemWindowScene is null. node:%{public}s",
250             GetWindowName(node).c_str());
251         return false;
252     }
253     auto session = windowPattern->GetSession();
254     if (session == nullptr) {
255         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent session is null. node:%{public}s",
256             GetWindowName(node).c_str());
257         return false;
258     }
259     return session->GetSystemTouchable();
260 }
261 
NoNeedSyncScenePanelGlobalPosition(const RefPtr<FrameNode> & node)262 bool WindowSceneLayoutManager::NoNeedSyncScenePanelGlobalPosition(const RefPtr<FrameNode>& node) // false: need sync
263 {
264     CHECK_NULL_RETURN(node, false);
265     if (!WindowSceneHelper::IsPanelScene(node->GetWindowPatternType())) {
266         return false;
267     }
268     auto windowPattern = node->GetPattern<PanelScene>();
269     if (windowPattern == nullptr) {
270         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent SystemWindowScene is null. node:%{public}s",
271             GetWindowName(node).c_str());
272         return false;
273     }
274     auto session = windowPattern->GetSession();
275     if (session == nullptr) {
276         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "recent session is null. node:%{public}s",
277             GetWindowName(node).c_str());
278         return false;
279     }
280     return !session->IsNeedSyncScenePanelGlobalPosition();
281 }
282 
IsFrameNodeAbnormal(const RefPtr<FrameNode> & node)283 void WindowSceneLayoutManager::IsFrameNodeAbnormal(const RefPtr<FrameNode>& node)
284 {
285     CHECK_NULL_VOID(node);
286     if (node->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
287         return;
288     }
289     auto windowScene = node->GetPattern<WindowScene>();
290     CHECK_NULL_VOID(windowScene);
291     auto session = windowScene->GetSession();
292     CHECK_NULL_VOID(session);
293     auto surfaceNode = session->GetSurfaceNode();
294     CHECK_NULL_VOID(surfaceNode);
295     if (!surfaceNode->GetParent()) {
296         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "node:%{public}d name:%{public}s is on ui tree but not rs tree, "
297             "screenId:%{public}" PRIu64, node->GetId(), GetWindowName(node).c_str(), GetScreenId(node));
298     }
299 }
300 
TraverseTree(const RefPtr<FrameNode> & rootNode,TraverseResult & res,bool isAncestorRecent,bool isAncestorDirty,bool notSyncPosition)301 void WindowSceneLayoutManager::TraverseTree(const RefPtr<FrameNode>& rootNode, TraverseResult& res,
302     bool isAncestorRecent, bool isAncestorDirty, bool notSyncPosition)
303 {
304     CHECK_NULL_VOID(rootNode);
305     auto parentType = rootNode->GetWindowPatternType();
306     for (auto& weakNode : rootNode->GetFrameChildren()) {
307         auto node = weakNode.Upgrade();
308         // when current layer is invisible, no need traverse next
309         if (!node || !IsNodeVisible(node)) {
310             continue;
311         }
312         // once delete in recent, need update Zorder
313         uint32_t currentZorder = res.zOrderCnt_;
314         if (WindowSceneHelper::IsWindowPattern(node)) {
315             currentZorder = std::max(res.zOrderCnt_, static_cast<uint32_t>(GetNodeZIndex(node)));
316         }
317         // only window pattern need cal zorder
318         bool hasWindowSession = WindowSceneHelper::HasWindowSession(node);
319         if (hasWindowSession) {
320             res.zOrderCnt_ = currentZorder++; // keep last zorder as current zorder
321         }
322         notSyncPosition = (notSyncPosition || NoNeedSyncScenePanelGlobalPosition(node));
323         // process recent and child node
324         if (isAncestorRecent || IsRecentContainerState(node)) {
325             isAncestorRecent = true;
326         } else {
327             if (isAncestorDirty || IsNodeDirty(node)) {
328                 isAncestorDirty = true;
329                 UpdateGeometry(node, rootNode, WindowSceneHelper::IsTransformScene(parentType));
330             }
331         }
332         // only window pattern but not transform scene need sync info
333         if (hasWindowSession) {
334             FillWindowSceneInfo(node, res, isAncestorRecent, notSyncPosition);
335             DumpNodeInfo(node, rootNode, "AfterFillWindowSceneInfo");
336         }
337 
338         res.zOrderCnt_ = currentZorder; // use cnt++ for next zorder cnt
339         auto type = node->GetWindowPatternType();
340         if (!WindowSceneHelper::IsSystemWindowScene(type) && WindowSceneHelper::IsSystemWindowScene(parentType)) {
341             TAG_LOGD(AceLogTag::ACE_WINDOW_PIPELINE, "name:%{public}s child of systemScene continue",
342                 GetWindowName(node).c_str());
343             continue; // calculate last system window scene next layer
344         }
345         if (isCoreDebugEnable_) {
346             TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "finish TraverseTree winId:%{public}d name:%{public}s"
347                 "idName:%{public}s tag:%{public}s zorder:%{public}u isAncestorRecent:%{public}d "
348                 "isAncestorDirty:%{public}d hasWindowSession:%{public}d notSyncPosition:%{public}d",
349                 GetWindowId(node), GetWindowName(node).c_str(),
350                 node->GetInspectorId()->c_str(), node->GetTag().c_str(), res.zOrderCnt_,
351                 isAncestorRecent, isAncestorDirty, hasWindowSession, notSyncPosition);
352         }
353         TraverseTree(node, res, isAncestorRecent, isAncestorDirty, notSyncPosition);
354     }
355 }
356 
357 // dump funcs
358 template<typename T>
GetWindowIdInner(const RefPtr<T> & windowPattern)359 uint32_t WindowSceneLayoutManager::GetWindowIdInner(const RefPtr<T>& windowPattern)
360 {
361     if (windowPattern == nullptr) {
362         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
363         return 0;
364     }
365     auto session = windowPattern->GetSession();
366     if (session == nullptr) {
367         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
368         return 0;
369     }
370     return session->GetWindowId();
371 }
372 
GetWindowId(const RefPtr<FrameNode> & node)373 uint32_t WindowSceneLayoutManager::GetWindowId(const RefPtr<FrameNode>& node)
374 {
375     CHECK_NULL_RETURN(node, 0);
376 
377     auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
378     switch (type) {
379         case WindowPatternType::DEFAULT:
380         case WindowPatternType::TRANSFORM_SCENE:
381             return 0; // invalid window Id
382         case WindowPatternType::PANEL_SCENE:
383             return GetWindowIdInner(node->GetPattern<PanelScene>());
384         case WindowPatternType::INPUT_SCENE:
385             return GetWindowIdInner(node->GetPattern<InputScene>());
386         case WindowPatternType::SYSTEM_WINDOW_SCENE: {
387             auto windowPattern = node->GetPattern<SystemWindowScene>();
388             if (windowPattern == nullptr || windowPattern->GetSession() == nullptr) {
389                 TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "SystemWindowScene or session is null. type:%{public}u", type);
390                 return 0;
391             }
392             return GetWindowIdInner(node->GetPattern<SystemWindowScene>());
393         }
394         case WindowPatternType::WINDOW_SCENE: {
395             return GetWindowIdInner(node->GetPattern<WindowScene>());
396         }
397         default:
398             break;
399     }
400     return 0;
401 }
402 
403 template<typename T>
GetWindowNameInner(const RefPtr<T> & windowPattern)404 std::string WindowSceneLayoutManager::GetWindowNameInner(const RefPtr<T>& windowPattern)
405 {
406     if (windowPattern == nullptr) {
407         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "windowPattern is null");
408         return {};
409     }
410     auto session = windowPattern->GetSession();
411     if (session == nullptr) {
412         TAG_LOGE(AceLogTag::ACE_WINDOW_PIPELINE, "window session is null");
413         return {};
414     }
415     return session->GetWindowName();
416 }
417 
GetWindowName(const RefPtr<FrameNode> & node)418 std::string WindowSceneLayoutManager::GetWindowName(const RefPtr<FrameNode>& node)
419 {
420     CHECK_NULL_RETURN(node, "");
421     std::string name;
422     auto type = static_cast<WindowPatternType>(node->GetWindowPatternType());
423     switch (type) {
424         case WindowPatternType::DEFAULT:
425         case WindowPatternType::TRANSFORM_SCENE:
426             break;
427         case WindowPatternType::PANEL_SCENE: {
428             name = GetWindowNameInner(node->GetPattern<PanelScene>());
429             break;
430         }
431         case WindowPatternType::INPUT_SCENE: {
432             name = GetWindowNameInner(node->GetPattern<InputScene>());
433             break;
434         }
435         case WindowPatternType::SYSTEM_WINDOW_SCENE: {
436             name = GetWindowNameInner(node->GetPattern<SystemWindowScene>());
437             break;
438         }
439         case WindowPatternType::WINDOW_SCENE: {
440             name = GetWindowNameInner(node->GetPattern<WindowScene>());
441             break;
442         }
443         default:
444             break;
445     }
446     return name + "_" + node->GetInspectorIdValue("") + "_" + node->GetTag();
447 }
448 
449 
DumpFlushInfo(uint64_t screenId,TraverseResult & res)450 void WindowSceneLayoutManager::DumpFlushInfo(uint64_t screenId, TraverseResult& res)
451 {
452     if (!isCoreDebugEnable_) {
453         return;
454     }
455     for (auto& [winId, uiParam] : res.uiParams_) {
456         TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "DumpFlushInfo screenId:%{public}" PRIu64 " windowId:%{public}d"
457             "name:%{public}s rect:%{public}s, scaleX:%{public}f, scaleY:%{public}f, transX:%{public}f"
458             "transY:%{public}f pivotX:%{public}f, pivotY:%{public}f zOrder:%{public}u, interactive:%{public}d",
459             screenId, winId, uiParam.sessionName_.c_str(), uiParam.rect_.ToString().c_str(), uiParam.scaleX_,
460             uiParam.scaleY_, uiParam.transX_, uiParam.transY_,
461             uiParam.pivotX_, uiParam.pivotY_, uiParam.zOrder_, uiParam.interactive_);
462     }
463 }
464 
GetRSNodeId(const RefPtr<FrameNode> & node)465 uint64_t WindowSceneLayoutManager::GetRSNodeId(const RefPtr<FrameNode>& node)
466 {
467     auto rsNode = GetRSNode(node);
468     CHECK_NULL_RETURN(rsNode, 0);
469     return rsNode->GetId();
470 }
471 
DumpNodeInfo(const RefPtr<FrameNode> & node,const RefPtr<FrameNode> & parentNode,const std::string & reason)472 void WindowSceneLayoutManager::DumpNodeInfo(const RefPtr<FrameNode>& node,
473     const RefPtr<FrameNode>& parentNode, const std::string& reason)
474 {
475     if (!isCoreDebugEnable_) {
476         return;
477     }
478     CHECK_NULL_VOID(node);
479     int32_t parentId = parentNode ? parentNode->GetId() : 0;
480     auto rsNode = GetRSNode(node);
481     CHECK_NULL_VOID(rsNode);
482     auto nodeGeometry = rsNode->GetGlobalGeometry();
483     if (!nodeGeometry) {
484         TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
485             "reason:%{public}s globalGeometry name:%{public}s lrsId:%{public}" PRIu64 " %{public}d"
486             "parentRSId:%{public}" PRIu64 " frameNodeId:%{public}d global geoMetry is null",
487             reason.c_str(), GetWindowName(node).c_str(), GetRSNodeId(node), node->GetId(),
488             GetRSNodeId(parentNode), parentId);
489         return;
490     }
491     auto nodeLocalGeometry = rsNode->GetLocalGeometry();
492     if (!nodeLocalGeometry) {
493         TAG_LOGW(AceLogTag::ACE_WINDOW_PIPELINE,
494             "reason:%{public}s localGeometry name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 ""
495             " localGeo is null", reason.c_str(), GetWindowName(node).c_str(),
496             GetRSNodeId(node), GetRSNodeId(parentNode));
497         return;
498     }
499 
500     Rosen::WSRect tempGlobal = { nodeGeometry->GetX(), nodeGeometry->GetY(),
501         nodeGeometry->GetWidth(), nodeGeometry->GetHeight() };
502     Rosen::WSRect tempLocal = { nodeLocalGeometry->GetX(), nodeLocalGeometry->GetY(),
503         nodeLocalGeometry->GetWidth(), nodeLocalGeometry->GetHeight() };
504     auto localMatrix = nodeLocalGeometry->GetAbsMatrix();
505     auto globalMatrix = nodeGeometry->GetAbsMatrix();
506     float localTransX = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
507     float localTransY = localMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
508     float globalTransX = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_X);
509     float globalTransY = globalMatrix.Get(Rosen::Drawing::Matrix::TRANS_Y);
510     auto absGlobalRect = nodeGeometry->GetAbsRect();
511     auto absLocalRect = nodeLocalGeometry->GetAbsRect();
512     auto localScaleX = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
513     auto localScaleY = localMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
514     auto gScaleX = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_X);
515     auto gScaleY = globalMatrix.Get(Rosen::Drawing::Matrix::SCALE_Y);
516     float globalPosX = rsNode->GetGlobalPositionX();
517     float globalPosY = rsNode->GetGlobalPositionY();
518     TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE,
519         "DumpNodeInfo reason:%{public}s name:%{public}s lrsId:%{public}" PRIu64 " parentRSId:%{public}" PRIu64 " "
520         "frameNodeId:%{public}d [Rect:%{public}s lTransX:%{public}f lTransY:%{public}f absLocalRect:%{public}s, "
521         "gRect:%{public}s gTransX:%{public}f gTransY:%{public}f globalPosX:%{public}f, globalPosY:%{public}f, "
522         "absGlobalRect:%{public}s lScaleX:%{public}f lScaleY:%{public}f gScaleX:%{public}f gScaleY:%{public}f]",
523         GetWindowName(node).c_str(), reason.c_str(), GetRSNodeId(node), GetRSNodeId(parentNode), parentId,
524         tempLocal.ToString().c_str(), localTransX, localTransY,
525         absLocalRect.ToString().c_str(), tempGlobal.ToString().c_str(), globalTransX, globalTransY, globalPosX,
526         globalPosY, absGlobalRect.ToString().c_str(), localScaleX, localScaleY, gScaleX, gScaleY);
527 }
528 
RegisterScreenNode(uint64_t screenId,const RefPtr<FrameNode> & node)529 void WindowSceneLayoutManager::RegisterScreenNode(uint64_t screenId, const RefPtr<FrameNode>& node)
530 {
531     screenNodeMap_[screenId] = WeakPtr<FrameNode>(node);
532     TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " register, size:%{public}d",
533         screenId, static_cast<uint32_t>(screenNodeMap_.size()));
534 }
535 
UnregisterScreenNode(uint64_t screenId)536 void WindowSceneLayoutManager::UnregisterScreenNode(uint64_t screenId)
537 {
538     screenNodeMap_.erase(screenId);
539     TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "screenNode:%{public}" PRIu64 " unregister, size:%{public}d",
540         screenId, static_cast<uint32_t>(screenNodeMap_.size()));
541 }
542 
GetUINodeInfo(const RefPtr<FrameNode> & node,int32_t parentId,std::ostringstream & oss)543 void WindowSceneLayoutManager::GetUINodeInfo(const RefPtr<FrameNode>& node,
544     int32_t parentId, std::ostringstream& oss)
545 {
546     CHECK_NULL_VOID(node);
547     auto context = AceType::DynamicCast<RosenRenderContext>(node->GetRenderContext());
548     CHECK_NULL_VOID(context);
549     auto rsNode = context->GetRSNode();
550     CHECK_NULL_VOID(rsNode);
551     oss << " name: " << GetWindowName(node);
552     oss << " isVisible: " << node->IsVisible();
553     oss << " opacity: " << context->GetOpacityValue(1.0f);
554     oss << " patternType: " << node->GetWindowPatternType();
555     auto globalGeometry = GetGlobalGeometry(node);
556     auto localGeometry = GetLocalGeometry(node);
557     if (globalGeometry && localGeometry) {
558         auto absRect = globalGeometry->GetAbsRect();
559         oss << " resRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
560             << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
561         auto matrix = globalGeometry->GetAbsMatrix();
562         oss << " globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
563             << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
564         oss << " globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "],";
565         oss << " pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "],";
566     } else {
567         oss << " globalGeometry: [null],";
568     }
569     if (localGeometry) {
570         auto absRect = localGeometry->GetAbsRect();
571         oss << " localRect: [" << absRect.GetLeft() << ", " << absRect.GetTop() << ", "
572             << localGeometry->GetWidth() << ", " << localGeometry->GetHeight() << "]";
573         auto matrix = localGeometry->GetAbsMatrix();
574         oss << " localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
575             << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "],";
576         oss << " localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
577             << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "],";
578         oss << " localPos: [" << localGeometry->GetX() << ", "
579             << localGeometry->GetY() << "],";
580     } else {
581         oss << " localGeometry: [null],";
582     }
583     oss << " requestZIndex: " << context->GetZIndexValue(ZINDEX_DEFAULT_VALUE);
584     oss << " rsId: " << GetRSNodeId(node);
585     oss << " frameNodeId: " << node->GetId();
586     oss << " parentFrameNodeId: " << parentId << std::endl;
587 }
588 
GetTotalUITreeInfo(std::string & info)589 void WindowSceneLayoutManager::GetTotalUITreeInfo(std::string& info)
590 {
591     if (!mainHandler_) {
592         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
593         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
594     }
595     auto task = [this, &info] {
596         for (auto it = screenNodeMap_.begin(); it != screenNodeMap_.end(); ++it) {
597             TAG_LOGI(AceLogTag::ACE_WINDOW_PIPELINE, "begin task GetTotalUITreeInfo:%{public}" PRIu64, it->first);
598             std::ostringstream oss;
599             auto screenNode = it->second.Upgrade();
600             GetUITreeInfo(screenNode, 0, 0, oss);
601             oss << "--------------------------------PatternTree" << " screenId: " <<
602                 it->first << "-----------------------------------" << std::endl;
603             GetRSNodeTreeInfo(GetRSNode(screenNode), 0, oss);
604             info.append(oss.str());
605         }
606     };
607     mainHandler_->PostSyncTask(std::move(task), "GetTotalUITreeInfo", AppExecFwk::EventQueue::Priority::IMMEDIATE);
608 }
609 
GetUITreeInfo(const RefPtr<FrameNode> & node,int32_t depth,int32_t parentId,std::ostringstream & oss)610 void WindowSceneLayoutManager::GetUITreeInfo(const RefPtr<FrameNode>& node, int32_t depth,
611     int32_t parentId, std::ostringstream& oss)
612 {
613     if (!node) {
614         return;
615     }
616     for (int32_t i = 0; i < depth; ++i) {
617         oss << "  ";
618     }
619     oss << "| ";
620     GetUINodeInfo(node, parentId, oss);
621     for (auto& weakNode : node->GetFrameChildren()) {
622         auto child = weakNode.Upgrade();
623         if (!child) {
624             continue;
625         }
626         GetUITreeInfo(child, depth + 1, node->GetId(), oss);
627     }
628 }
629 
DumpRSNodeType(Rosen::RSUINodeType nodeType,std::ostringstream & oss)630 void WindowSceneLayoutManager::DumpRSNodeType(Rosen::RSUINodeType nodeType, std::ostringstream& oss)
631 {
632     switch (nodeType) {
633         case Rosen::RSUINodeType::DISPLAY_NODE: {
634             oss << "DISPLAY_NODE";
635             break;
636         }
637         case Rosen::RSUINodeType::RS_NODE: {
638             oss << "RS_NODE";
639             break;
640         }
641         case Rosen::RSUINodeType::SURFACE_NODE: {
642             oss << "SURFACE_NODE";
643             break;
644         }
645         case Rosen::RSUINodeType::CANVAS_NODE: {
646             oss << "CANVAS_NODE";
647             break;
648         }
649         case Rosen::RSUINodeType::ROOT_NODE: {
650             oss << "ROOT_NODE";
651             break;
652         }
653         case Rosen::RSUINodeType::PROXY_NODE: {
654             oss << "PROXY_NODE";
655             break;
656         }
657         case Rosen::RSUINodeType::CANVAS_DRAWING_NODE: {
658             oss << "CANVAS_DRAWING_NODE";
659             break;
660         }
661         case Rosen::RSUINodeType::EFFECT_NODE: {
662             oss << "EFFECT_NODE";
663             break;
664         }
665         default: {
666             oss << "UNKNOWN_NODE";
667             break;
668         }
669     }
670 }
671 
GetRSNodeTreeInfo(const std::shared_ptr<RSNode> & rsNode,int32_t depth,std::ostringstream & oss)672 void WindowSceneLayoutManager::GetRSNodeTreeInfo(const std::shared_ptr<RSNode>& rsNode, int32_t depth,
673     std::ostringstream& oss)
674 {
675     CHECK_NULL_VOID(rsNode);
676     for (int32_t i = 0; i < depth; ++i) {
677         oss << "  ";
678     }
679     oss << "| ";
680     GetRSNodeInfo(rsNode, oss);
681     auto children = rsNode->GetChildren();
682     for (auto child : children) {
683         if (auto childPtr = Rosen::RSNodeMap::Instance().GetNode(child)) {
684             GetRSNodeTreeInfo(childPtr, depth + 1, oss);
685         }
686     }
687 }
688 
GetRSNodeInfo(const std::shared_ptr<RSNode> & rsNode,std::ostringstream & oss)689 void WindowSceneLayoutManager::GetRSNodeInfo(const std::shared_ptr<RSNode>& rsNode,
690     std::ostringstream& oss)
691 {
692     CHECK_NULL_VOID(rsNode);
693     DumpRSNodeType(rsNode->GetType(), oss);
694     oss << "[" + std::to_string(rsNode->GetId()) << "], ";
695     if (rsNode->GetType() == Rosen::RSUINodeType::SURFACE_NODE) {
696         auto surfaceNode = Rosen::RSNode::ReinterpretCast<Rosen::RSSurfaceNode>(rsNode);
697         std::string name = surfaceNode ? surfaceNode->GetName() : "";
698         oss << "Name [" << name << "]";
699     }
700     oss << ", StagingProperties" << rsNode->GetStagingProperties().Dump();
701     auto scale = rsNode->GetStagingProperties().GetScale();
702     oss << ", Scale: [" << scale[0] << ", " << scale[1] << "]";
703     auto translate = rsNode->GetStagingProperties().GetTranslate();
704     oss << ", Translate: [" << translate[0] << ", " << translate[1] << ", "
705         << rsNode->GetStagingProperties().GetTranslateZ() << "]";
706     oss << ", Rotation: " << rsNode->GetStagingProperties().GetRotation();
707     oss << ", Alpha: " << rsNode->GetStagingProperties().GetAlpha();
708     oss << ", ClipToBounds: " << rsNode->GetStagingProperties().GetClipBounds();
709     auto globalGeometry = rsNode->GetGlobalGeometry();
710     if (globalGeometry) {
711         auto absRect = globalGeometry->GetAbsRect();
712         oss << ", globalAbsRect: " << absRect.ToString().c_str();
713         auto matrix = globalGeometry->GetAbsMatrix();
714         oss << ", globalScale: [ " << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
715             << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
716         oss << ", globalPos: [" << rsNode->GetGlobalPositionX() << ", " << rsNode->GetGlobalPositionY() << "]";
717         oss << ", pivot: [" << globalGeometry->GetPivotX() << ", " << globalGeometry->GetPivotY() << "]";
718     } else {
719         oss << "globalGeometry: [null],";
720     }
721     auto localGeometry = rsNode->GetLocalGeometry();
722     if (localGeometry) {
723         auto absRect = localGeometry->GetAbsRect();
724         oss << ", localAbsRect: " << absRect.ToString().c_str();
725         auto matrix = localGeometry->GetAbsMatrix();
726         oss << ", localScale: [" << matrix.Get(Rosen::Drawing::Matrix::SCALE_X) << ", "
727             << matrix.Get(Rosen::Drawing::Matrix::SCALE_Y) << "]";
728         oss << ", localTrans: [" << matrix.Get(Rosen::Drawing::Matrix::TRANS_X) << ", "
729             << matrix.Get(Rosen::Drawing::Matrix::TRANS_Y) << "]";
730         oss << ", localPos: [" << localGeometry->GetX() << ", " << localGeometry->GetY() << "]";
731     } else {
732         oss << "localGeometry: [null],";
733     }
734     oss << std::endl;
735 }
736 } // namespace OHOS::Ace::NG