1 /*
2 * Copyright (c) 2022-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
16 #include "core/components_ng/base/inspector.h"
17
18 #include <unistd.h>
19 #include <unordered_set>
20
21 #include "base/memory/ace_type.h"
22 #include "base/utils/utils.h"
23 #include "core/common/ace_application_info.h"
24 #include "core/common/recorder/event_recorder.h"
25 #include "core/components_ng/base/inspector_filter.h"
26 #include "core/components_ng/base/ui_node.h"
27 #include "core/components_ng/pattern/custom/custom_node.h"
28 #include "core/components_ng/pattern/stage/page_info.h"
29 #include "core/components_ng/pattern/stage/page_pattern.h"
30 #include "core/components_ng/pattern/text/span_node.h"
31 #include "core/components_ng/render/render_context.h"
32 #include "foundation/arkui/ace_engine/frameworks/base/utils/utf.h"
33
34 namespace OHOS::Ace::NG {
35 namespace {
36 const char INSPECTOR_TYPE[] = "$type";
37 const char INSPECTOR_ID[] = "$ID";
38 const char INSPECTOR_RECT[] = "$rect";
39 const char INSPECTOR_ATTRS[] = "$attrs";
40 const char INSPECTOR_ROOT[] = "root";
41 const char INSPECTOR_PAGE_URL[] = "pageUrl";
42 const char INSPECTOR_NAV_DST_NAME[] = "navDstName";
43 const char INSPECTOR_WIDTH[] = "width";
44 const char INSPECTOR_HEIGHT[] = "height";
45 const char INSPECTOR_RESOLUTION[] = "$resolution";
46 const char INSPECTOR_CHILDREN[] = "$children";
47 const char INSPECTOR_DEBUGLINE[] = "$debugLine";
48 #ifdef PREVIEW
49 const char INSPECTOR_VIEW_ID[] = "$viewID";
50 #else
51 const char INSPECTOR_CUSTOM_VIEW_TAG[] = "viewTag";
52 const char INSPECTOR_COMPONENT_TYPE[] = "type";
53 const char INSPECTOR_STATE_VAR[] = "state";
54 #endif
55 const char INSPECTOR_ATTR_ID[] = "id";
56 const char INSPECTOR_LABEL[] = "label";
57 const char INSPECTOR_CONTENT[] = "content";
58 const char INSPECTOR_ENABLED[] = "enabled";
59 const char INSPECTOR_OPACITY[] = "opacity";
60 const char INSPECTOR_ZINDEX[] = "zindex";
61 const char INSPECTOR_VISIBILITY[] = "visibility";
62
63
64 const uint32_t LONG_PRESS_DELAY = 1000;
65 RectF deviceRect;
66
GetInspectorByKey(const RefPtr<FrameNode> & root,const std::string & key,bool notDetach=false)67 RefPtr<UINode> GetInspectorByKey(const RefPtr<FrameNode>& root, const std::string& key, bool notDetach = false)
68 {
69 std::queue<RefPtr<UINode>> elements;
70 elements.push(root);
71 RefPtr<UINode> inspectorElement;
72 while (!elements.empty()) {
73 auto current = elements.front();
74 elements.pop();
75 if (key == current->GetInspectorId().value_or("")) {
76 return current;
77 }
78
79 const auto& children = current->GetChildren(notDetach);
80 for (const auto& child : children) {
81 elements.push(child);
82 }
83 }
84 return nullptr;
85 }
86
DumpElementTree(int32_t depth,const RefPtr<UINode> & element,std::map<int32_t,std::list<RefPtr<UINode>>> & depthElementMap)87 void DumpElementTree(
88 int32_t depth, const RefPtr<UINode>& element, std::map<int32_t, std::list<RefPtr<UINode>>>& depthElementMap)
89 {
90 if (element->GetChildren().empty()) {
91 return;
92 }
93 const auto& children = element->GetChildren();
94 depthElementMap[depth].insert(depthElementMap[depth].end(), children.begin(), children.end());
95 for (const auto& depthElement : children) {
96 DumpElementTree(depth + 1, depthElement, depthElementMap);
97 }
98 }
99
GetUpPoint(const TouchEvent & downPoint)100 TouchEvent GetUpPoint(const TouchEvent& downPoint)
101 {
102 return TouchEvent {}
103 .SetX(downPoint.x)
104 .SetY(downPoint.y)
105 .SetType(TouchType::UP)
106 .SetTime(std::chrono::high_resolution_clock::now())
107 .SetSourceType(SourceType::TOUCH);
108 }
109 #ifdef PREVIEW
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::vector<RefPtr<NG::UINode>> & children,int32_t pageId,bool isLayoutInspector=false)110 void GetFrameNodeChildren(const RefPtr<NG::UINode>& uiNode, std::vector<RefPtr<NG::UINode>>& children, int32_t pageId,
111 bool isLayoutInspector = false)
112 {
113 // Set ViewId for the fast preview.
114 auto parent = uiNode->GetParent();
115 if (parent && parent->GetTag() == "JsView") {
116 uiNode->SetViewId(std::to_string(parent->GetId()));
117 } else {
118 uiNode->SetViewId(parent->GetViewId());
119 }
120 if (uiNode->GetTag() == "stage") {
121 } else if (uiNode->GetTag() == "page") {
122 if (uiNode->GetPageId() != pageId) {
123 return;
124 }
125 } else {
126 if (!uiNode->GetDebugLine().empty()) {
127 children.emplace_back(uiNode);
128 return;
129 }
130 }
131
132 for (const auto& frameChild : uiNode->GetChildren()) {
133 GetFrameNodeChildren(frameChild, children, pageId);
134 }
135 }
136
GetSpanInspector(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId)137 void GetSpanInspector(
138 const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray, int pageId)
139 {
140 // span rect follows parent text size
141 auto spanParentNode = parent->GetParent();
142 while (spanParentNode != nullptr) {
143 if (AceType::InstanceOf<NG::FrameNode>(spanParentNode)) {
144 break;
145 }
146 spanParentNode = spanParentNode->GetParent();
147 }
148 CHECK_NULL_VOID(spanParentNode);
149 auto node = AceType::DynamicCast<FrameNode>(spanParentNode);
150 auto jsonNode = JsonUtil::Create(true);
151 auto jsonObject = JsonUtil::Create(true);
152
153 InspectorFilter filter;
154 parent->ToJsonValue(jsonObject, filter);
155 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonObject));
156 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
157 jsonNode->Put(INSPECTOR_ID, parent->GetId());
158 RectF rect = node->GetTransformRectRelativeToWindow();
159 rect = rect.Constrain(deviceRect);
160 if (rect.IsEmpty()) {
161 rect.SetRect(0, 0, 0, 0);
162 }
163 auto strRec = std::to_string(rect.Left())
164 .append(",")
165 .append(std::to_string(rect.Top()))
166 .append(",")
167 .append(std::to_string(rect.Width()))
168 .append(",")
169 .append(std::to_string(rect.Height()));
170 jsonNode->Put(INSPECTOR_RECT, strRec.c_str());
171 jsonNode->Put(INSPECTOR_DEBUGLINE, parent->GetDebugLine().c_str());
172 jsonNode->Put(INSPECTOR_VIEW_ID, parent->GetViewId().c_str());
173 jsonNodeArray->PutRef(std::move(jsonNode));
174 }
175
GetInspectorChildren(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId,bool isActive,const InspectorFilter & filter=InspectorFilter (),uint32_t depth=UINT32_MAX,bool isLayoutInspector=false)176 void GetInspectorChildren(const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray,
177 int pageId, bool isActive, const InspectorFilter& filter = InspectorFilter(), uint32_t depth = UINT32_MAX,
178 bool isLayoutInspector = false)
179 {
180 // Span is a special case in Inspector since span inherits from UINode
181 if (AceType::InstanceOf<SpanNode>(parent)) {
182 GetSpanInspector(parent, jsonNodeArray, pageId);
183 return;
184 }
185 auto jsonNode = JsonUtil::Create(true);
186 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
187 jsonNode->Put(INSPECTOR_ID, parent->GetId());
188 auto node = AceType::DynamicCast<FrameNode>(parent);
189 if (node) {
190 RectF rect;
191 isActive = isActive && node->IsActive();
192 if (isActive) {
193 rect = node->GetTransformRectRelativeToWindow();
194 }
195 rect = rect.Constrain(deviceRect);
196 if (rect.IsEmpty()) {
197 rect.SetRect(0, 0, 0, 0);
198 }
199 auto strRec = std::to_string(rect.Left()).append(",")
200 .append(std::to_string(rect.Top())).append(",")
201 .append(std::to_string(rect.Width())).append(",")
202 .append(std::to_string(rect.Height()));
203 jsonNode->Put(INSPECTOR_RECT, strRec.c_str());
204 jsonNode->Put(INSPECTOR_DEBUGLINE, node->GetDebugLine().c_str());
205 jsonNode->Put(INSPECTOR_VIEW_ID, node->GetViewId().c_str());
206 auto jsonObject = JsonUtil::Create(true);
207
208 InspectorFilter filter;
209 parent->ToJsonValue(jsonObject, filter);
210 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonObject));
211 }
212
213 std::vector<RefPtr<NG::UINode>> children;
214 for (const auto& item : parent->GetChildren()) {
215 GetFrameNodeChildren(item, children, pageId);
216 }
217 if (node != nullptr) {
218 auto overlayNode = node->GetOverlayNode();
219 if (overlayNode != nullptr) {
220 GetFrameNodeChildren(overlayNode, children, pageId);
221 }
222 }
223 if (depth) {
224 auto jsonChildrenArray = JsonUtil::CreateArray(true);
225 for (auto uiNode : children) {
226 GetInspectorChildren(uiNode, jsonChildrenArray, pageId, isActive, filter, depth - 1);
227 }
228 if (jsonChildrenArray->GetArraySize()) {
229 jsonNode->PutRef(INSPECTOR_CHILDREN, std::move(jsonChildrenArray));
230 }
231 }
232 jsonNodeArray->PutRef(std::move(jsonNode));
233 }
234
235 #else
GetFrameNodeChildren(const RefPtr<NG::UINode> & uiNode,std::vector<RefPtr<NG::UINode>> & children,int32_t pageId,bool isLayoutInspector=false)236 void GetFrameNodeChildren(const RefPtr<NG::UINode>& uiNode, std::vector<RefPtr<NG::UINode>>& children,
237 int32_t pageId, bool isLayoutInspector = false)
238 {
239 if (AceType::InstanceOf<NG::FrameNode>(uiNode) || AceType::InstanceOf<SpanNode>(uiNode) ||
240 AceType::InstanceOf<CustomNode>(uiNode)) {
241 if (uiNode->GetTag() == "stage") {
242 } else if (uiNode->GetTag() == "page") {
243 if (uiNode->GetPageId() != pageId) {
244 return;
245 }
246 } else {
247 auto custom = AceType::DynamicCast<NG::CustomNode>(uiNode);
248 auto frameNode = AceType::DynamicCast<NG::FrameNode>(uiNode);
249 auto spanNode = AceType::DynamicCast<NG::SpanNode>(uiNode);
250 if ((frameNode && !frameNode->IsInternal()) || spanNode || (custom && isLayoutInspector)) {
251 children.emplace_back(uiNode);
252 return;
253 }
254 }
255 }
256 for (const auto& frameChild : uiNode->GetChildren()) {
257 GetFrameNodeChildren(frameChild, children, pageId, isLayoutInspector);
258 }
259 }
260
GetSpanInspector(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId)261 void GetSpanInspector(
262 const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray, int pageId)
263 {
264 // span rect follows parent text size
265 auto spanParentNode = parent->GetParent();
266 while (spanParentNode != nullptr) {
267 if (AceType::InstanceOf<NG::FrameNode>(spanParentNode)) {
268 break;
269 }
270 spanParentNode = spanParentNode->GetParent();
271 }
272 CHECK_NULL_VOID(spanParentNode);
273 auto node = AceType::DynamicCast<FrameNode>(spanParentNode);
274 auto jsonNode = JsonUtil::Create(true);
275 auto jsonObject = JsonUtil::Create(true);
276
277 InspectorFilter filter;
278 parent->ToJsonValue(jsonObject, filter);
279 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonObject));
280 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
281 jsonNode->Put(INSPECTOR_ID, parent->GetId());
282 jsonNode->Put(INSPECTOR_DEBUGLINE, parent->GetDebugLine().c_str());
283 RectF rect = node->GetTransformRectRelativeToWindow();
284 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
285 jsonNodeArray->PutRef(std::move(jsonNode));
286 }
287
GetCustomNodeInfo(const RefPtr<NG::UINode> & customNode,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode)288 void GetCustomNodeInfo(const RefPtr<NG::UINode> &customNode, std::unique_ptr<OHOS::Ace::JsonValue> &jsonNode)
289 {
290 // custom node rect follows parent size
291 auto hostNode = customNode->GetParent();
292 while (hostNode != nullptr) {
293 if (AceType::InstanceOf<NG::FrameNode>(hostNode)) {
294 break;
295 }
296 hostNode = hostNode->GetParent();
297 }
298 CHECK_NULL_VOID(hostNode);
299 jsonNode->Put(INSPECTOR_COMPONENT_TYPE, "custom");
300 auto node = AceType::DynamicCast<CustomNode>(customNode);
301 CHECK_NULL_VOID(node);
302 auto parentNode = AceType::DynamicCast<FrameNode>(hostNode);
303 jsonNode->Put(INSPECTOR_STATE_VAR, node->GetStateInspectorInfo());
304 RectF rect = parentNode->GetTransformRectRelativeToWindow();
305 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
306 jsonNode->Put(INSPECTOR_DEBUGLINE, customNode->GetDebugLine().c_str());
307 jsonNode->Put(INSPECTOR_CUSTOM_VIEW_TAG, node->GetCustomTag().c_str());
308 }
309
GetInspectorChildren(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId,bool isActive,const InspectorFilter & filter=InspectorFilter (),uint32_t depth=UINT32_MAX,bool isLayoutInspector=false)310 void GetInspectorChildren(const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray,
311 int pageId, bool isActive, const InspectorFilter& filter = InspectorFilter(), uint32_t depth = UINT32_MAX,
312 bool isLayoutInspector = false)
313 {
314 // Span is a special case in Inspector since span inherits from UINode
315 if (AceType::InstanceOf<SpanNode>(parent)) {
316 GetSpanInspector(parent, jsonNodeArray, pageId);
317 return;
318 }
319 if (AceType::InstanceOf<CustomNode>(parent) && !isLayoutInspector) {
320 return;
321 }
322 auto jsonNode = JsonUtil::Create(true);
323 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
324 jsonNode->Put(INSPECTOR_ID, parent->GetId());
325 if (parent->GetTag() == V2::JS_VIEW_ETS_TAG) {
326 GetCustomNodeInfo(parent, jsonNode);
327 } else {
328 jsonNode->Put(INSPECTOR_COMPONENT_TYPE, "build-in");
329 }
330 auto node = AceType::DynamicCast<FrameNode>(parent);
331 if (node) {
332 RectF rect;
333 isActive = isActive && node->IsActive();
334 if (isActive) {
335 rect = node->GetTransformRectRelativeToWindow();
336 }
337 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
338 jsonNode->Put(INSPECTOR_DEBUGLINE, node->GetDebugLine().c_str());
339 }
340 auto jsonObject = JsonUtil::Create(true);
341 parent->ToJsonValue(jsonObject, filter);
342 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonObject));
343 std::string jsonNodeStr = jsonNode->ToString();
344 ConvertIllegalStr(jsonNodeStr);
345 auto jsonNodeNew = JsonUtil::ParseJsonString(jsonNodeStr);
346 std::vector<RefPtr<NG::UINode>> children;
347 for (const auto& item : parent->GetChildren()) {
348 GetFrameNodeChildren(item, children, pageId, isLayoutInspector);
349 }
350 if (node) {
351 auto overlayNode = node->GetOverlayNode();
352 if (overlayNode != nullptr) {
353 GetFrameNodeChildren(overlayNode, children, pageId, isLayoutInspector);
354 }
355 }
356 if (depth) {
357 auto jsonChildrenArray = JsonUtil::CreateArray(true);
358 for (auto uiNode : children) {
359 GetInspectorChildren(uiNode, jsonChildrenArray, pageId, isActive, filter, depth - 1, isLayoutInspector);
360 }
361 if (jsonChildrenArray->GetArraySize()) {
362 jsonNodeNew->PutRef(INSPECTOR_CHILDREN, std::move(jsonChildrenArray));
363 }
364 }
365 jsonNodeArray->PutRef(std::move(jsonNodeNew));
366 }
367 #endif
368
GetOverlayNode(const RefPtr<NG::UINode> & pageNode)369 RefPtr<NG::UINode> GetOverlayNode(const RefPtr<NG::UINode>& pageNode)
370 {
371 CHECK_NULL_RETURN(pageNode, nullptr);
372 auto stageNode = pageNode->GetParent();
373 CHECK_NULL_RETURN(stageNode, nullptr);
374 auto stageParent = stageNode->GetParent();
375 CHECK_NULL_RETURN(stageParent, nullptr);
376 auto overlayNode = stageParent->GetChildren().back();
377 if (overlayNode->GetTag() == "stage") {
378 return nullptr;
379 }
380 return overlayNode;
381 }
382
GetContextInfo(const RefPtr<PipelineContext> & context,std::unique_ptr<JsonValue> & jsonRoot)383 void GetContextInfo(const RefPtr<PipelineContext>& context, std::unique_ptr<JsonValue>& jsonRoot)
384 {
385 auto scale = context->GetViewScale();
386 auto rootHeight = context->GetRootHeight();
387 auto rootWidth = context->GetRootWidth();
388 deviceRect.SetRect(0, 0, rootWidth * scale, rootHeight * scale);
389 jsonRoot->Put(INSPECTOR_WIDTH, std::to_string(rootWidth * scale).c_str());
390 jsonRoot->Put(INSPECTOR_HEIGHT, std::to_string(rootHeight * scale).c_str());
391 jsonRoot->Put(INSPECTOR_RESOLUTION, std::to_string(PipelineBase::GetCurrentDensity()).c_str());
392 }
393
GetInspectorInfo(std::vector<RefPtr<NG::UINode>> children,int32_t pageId,std::unique_ptr<JsonValue> jsonRoot,bool isLayoutInspector,const InspectorFilter & filter=InspectorFilter ())394 std::string GetInspectorInfo(std::vector<RefPtr<NG::UINode>> children, int32_t pageId,
395 std::unique_ptr<JsonValue> jsonRoot, bool isLayoutInspector, const InspectorFilter& filter = InspectorFilter())
396 {
397 auto jsonNodeArray = JsonUtil::CreateArray(true);
398 auto depth = filter.GetFilterDepth();
399 for (auto& uiNode : children) {
400 GetInspectorChildren(uiNode, jsonNodeArray, pageId, true, filter, depth - 1, isLayoutInspector);
401 }
402 if (jsonNodeArray->GetArraySize()) {
403 jsonRoot->PutRef(INSPECTOR_CHILDREN, std::move(jsonNodeArray));
404 }
405
406 if (isLayoutInspector) {
407 auto jsonTree = JsonUtil::Create(true);
408 jsonTree->Put("type", "root");
409 jsonTree->PutRef("content", std::move(jsonRoot));
410 auto pipeline = PipelineContext::GetCurrentContextSafely();
411 if (pipeline) {
412 jsonTree->Put("VsyncID", (int32_t)pipeline->GetFrameCount());
413 jsonTree->Put("ProcessID", getpid());
414 jsonTree->Put("WindowID", (int32_t)pipeline->GetWindowId());
415 }
416 return jsonTree->ToString();
417 }
418
419 return jsonRoot->ToString();
420 }
421 } // namespace
422
423 std::set<RefPtr<FrameNode>> Inspector::offscreenNodes;
424
GetFrameNodeByKey(const std::string & key,bool notDetach)425 RefPtr<FrameNode> Inspector::GetFrameNodeByKey(const std::string& key, bool notDetach)
426 {
427 if (!offscreenNodes.empty()) {
428 for (auto node : offscreenNodes) {
429 auto frameNode = AceType::DynamicCast<FrameNode>(GetInspectorByKey(node, key, notDetach));
430 if (frameNode) {
431 return frameNode;
432 }
433 }
434 }
435 auto context = NG::PipelineContext::GetCurrentContext();
436 if (!context) {
437 LOGW("Internal error! Context is null. key: %{public}s", key.c_str());
438 return nullptr;
439 }
440 auto rootNode = context->GetRootElement();
441 if (!rootNode) {
442 LOGW("Internal error! RootNode is null. key: %{public}s", key.c_str());
443 return nullptr;
444 }
445
446 return AceType::DynamicCast<FrameNode>(GetInspectorByKey(rootNode, key, notDetach));
447 }
448
GetInspectorNodeByKey(const std::string & key,const InspectorFilter & filter)449 std::string Inspector::GetInspectorNodeByKey(const std::string& key, const InspectorFilter& filter)
450 {
451 auto context = NG::PipelineContext::GetCurrentContext();
452 CHECK_NULL_RETURN(context, "");
453 auto rootNode = context->GetRootElement();
454 CHECK_NULL_RETURN(rootNode, "");
455
456 auto inspectorElement = GetInspectorByKey(rootNode, key);
457 CHECK_NULL_RETURN(inspectorElement, "");
458
459 auto jsonNode = JsonUtil::Create(true);
460 jsonNode->Put(INSPECTOR_TYPE, inspectorElement->GetTag().c_str());
461 jsonNode->Put(INSPECTOR_ID, inspectorElement->GetId());
462 auto frameNode = AceType::DynamicCast<FrameNode>(inspectorElement);
463 if (frameNode) {
464 auto rect = frameNode->GetTransformRectRelativeToWindow();
465 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
466 }
467 auto jsonAttrs = JsonUtil::Create(true);
468 std::string debugLine = inspectorElement->GetDebugLine();
469 jsonNode->Put(INSPECTOR_DEBUGLINE, debugLine.c_str());
470
471 inspectorElement->ToJsonValue(jsonAttrs, filter);
472 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonAttrs));
473 return jsonNode->ToString();
474 }
475
GetRectangleById(const std::string & key,Rectangle & rectangle)476 void Inspector::GetRectangleById(const std::string& key, Rectangle& rectangle)
477 {
478 auto frameNode = Inspector::GetFrameNodeByKey(key, true);
479 if (!frameNode) {
480 LOGW("Can't find component:%{public}s, check your parameters", key.c_str());
481 return;
482 }
483 rectangle.size = frameNode->GetGeometryNode()->GetFrameSize();
484 auto context = frameNode->GetRenderContext();
485 if (!context) {
486 LOGW("Internal error! Component(id=%{public}s) is null", key.c_str());
487 return;
488 }
489 rectangle.localOffset = context->GetPaintRectWithTransform().GetOffset();
490 rectangle.windowOffset = frameNode->GetOffsetRelativeToWindow();
491 auto pipeline = frameNode->GetContext();
492 CHECK_NULL_VOID(pipeline);
493 rectangle.screenRect = pipeline->GetCurrentWindowRect();
494 ACE_SCOPED_TRACE("Inspector::GetRectangleById_Id=%d_Tag=%s_Key=%s",
495 frameNode->GetId(), frameNode->GetTag().c_str(), key.c_str());
496 LOGI("GetRectangleById Id:%{public}d key:%{public}s tag:%{public}s localOffset:%{public}s"
497 " windowOffset:%{public}s screenRect:%{public}s",
498 frameNode->GetId(), key.c_str(), frameNode->GetTag().c_str(), rectangle.localOffset.ToString().c_str(),
499 rectangle.windowOffset.ToString().c_str(), rectangle.screenRect.ToString().c_str());
500 auto renderContext = frameNode->GetRenderContext();
501 CHECK_NULL_VOID(renderContext);
502 Matrix4 defMatrix4 = Matrix4::CreateIdentity();
503 Matrix4 matrix4 = renderContext->GetTransformMatrixValue(defMatrix4);
504 rectangle.matrix4 = matrix4;
505 auto rect = renderContext->GetPaintRectWithoutTransform();
506 const double halfDimension = 50.0;
507 auto center = renderContext->GetTransformCenter().value_or(DimensionOffset(
508 Dimension(halfDimension, DimensionUnit::PERCENT), Dimension(halfDimension, DimensionUnit::PERCENT)));
509 double centerX = 0.0;
510 double centerY = 0.0;
511 if (center.GetX().Unit() == DimensionUnit::PERCENT || center.GetY().Unit() == DimensionUnit::PERCENT) {
512 if (rect.IsValid()) {
513 centerX = Dimension(center.GetX().ConvertToPxWithSize(rect.Width()), DimensionUnit::PX).ConvertToVp();
514 centerY = Dimension(center.GetY().ConvertToPxWithSize(rect.Height()), DimensionUnit::PX).ConvertToVp();
515 }
516 } else {
517 centerX = center.GetX().ConvertToVp();
518 centerY = center.GetY().ConvertToVp();
519 }
520 VectorF defScale = VectorF(1.0, 1.0);
521 VectorF scale = renderContext->GetTransformScaleValue(defScale);
522 rectangle.scale.x = scale.x;
523 rectangle.scale.y = scale.y;
524 rectangle.scale.z = 1.0;
525 rectangle.scale.centerX = centerX;
526 rectangle.scale.centerY = centerY;
527 Vector5F defRotate = Vector5F(0.0, 0.0, 0.0, 0.0, 0.0);
528 Vector5F rotate = renderContext->GetTransformRotateValue(defRotate);
529 rectangle.rotate.x = rotate.x;
530 rectangle.rotate.y = rotate.y;
531 rectangle.rotate.z = rotate.z;
532 rectangle.rotate.angle = rotate.w;
533 rectangle.rotate.centerX = centerX;
534 rectangle.rotate.centerY = centerY;
535 TranslateOptions defTranslate = TranslateOptions(0.0, 0.0, 0.0);
536 TranslateOptions translate = renderContext->GetTransformTranslateValue(defTranslate);
537 if ((translate.x.Unit() == DimensionUnit::PERCENT) && rect.IsValid()) {
538 rectangle.translate.x =
539 Dimension(translate.x.ConvertToPxWithSize(rect.Width()), DimensionUnit::PX).ConvertToVp();
540 } else {
541 rectangle.translate.x = translate.x.ConvertToVp();
542 }
543 if ((translate.y.Unit() == DimensionUnit::PERCENT) && rect.IsValid()) {
544 rectangle.translate.y =
545 Dimension(translate.y.ConvertToPxWithSize(rect.Height()), DimensionUnit::PX).ConvertToVp();
546 } else {
547 rectangle.translate.y = translate.y.ConvertToVp();
548 }
549 rectangle.translate.z = translate.z.ConvertToVp();
550 }
551
GetInspector(bool isLayoutInspector)552 std::string Inspector::GetInspector(bool isLayoutInspector)
553 {
554 InspectorFilter filter;
555 bool needThrow = false;
556 return GetInspector(isLayoutInspector, filter, needThrow);
557 }
558
GetInspector(bool isLayoutInspector,const InspectorFilter & filter,bool & needThrow)559 std::string Inspector::GetInspector(bool isLayoutInspector, const InspectorFilter& filter, bool& needThrow)
560 {
561 auto jsonRoot = JsonUtil::Create(true);
562 jsonRoot->Put(INSPECTOR_TYPE, INSPECTOR_ROOT);
563 needThrow = false;
564 auto context = NG::PipelineContext::GetCurrentContext();
565 if (context == nullptr) {
566 needThrow = true;
567 return jsonRoot->ToString();
568 }
569 GetContextInfo(context, jsonRoot);
570
571 RefPtr<UINode> pageRootNode;
572 const std::string key = filter.GetFilterID();
573 if (key.empty()) {
574 pageRootNode = context->GetStageManager()->GetLastPage();
575 } else {
576 auto rootNode = context->GetStageManager()->GetLastPage();
577 if (rootNode == nullptr) {
578 needThrow = true;
579 return jsonRoot->ToString();
580 }
581 pageRootNode = GetInspectorByKey(rootNode, key);
582 }
583 if (pageRootNode == nullptr) {
584 needThrow = true;
585 return jsonRoot->ToString();
586 }
587 auto pageId = context->GetStageManager()->GetLastPage()->GetPageId();
588 std::vector<RefPtr<NG::UINode>> children;
589 if (key.empty()) {
590 for (const auto& item : pageRootNode->GetChildren()) {
591 GetFrameNodeChildren(item, children, pageId, isLayoutInspector);
592 }
593 auto overlayNode = GetOverlayNode(pageRootNode);
594 if (overlayNode) {
595 GetFrameNodeChildren(overlayNode, children, pageId, isLayoutInspector);
596 }
597 } else {
598 children.emplace_back(pageRootNode);
599 }
600 return GetInspectorInfo(children, pageId, std::move(jsonRoot), isLayoutInspector, filter);
601 }
602
GetInspectorOfNode(RefPtr<NG::UINode> node)603 std::string Inspector::GetInspectorOfNode(RefPtr<NG::UINode> node)
604 {
605 auto jsonRoot = JsonUtil::Create(true);
606
607 auto context = NG::PipelineContext::GetCurrentContext();
608 CHECK_NULL_RETURN(context, jsonRoot->ToString());
609 GetContextInfo(context, jsonRoot);
610 CHECK_NULL_RETURN(node, jsonRoot->ToString());
611 auto pageId = context->GetStageManager()->GetLastPage()->GetPageId();
612 auto jsonNodeArray = JsonUtil::CreateArray(true);
613 GetInspectorChildren(node, jsonNodeArray, pageId, true, InspectorFilter(), 0);
614 if (jsonNodeArray->GetArraySize()) {
615 jsonRoot = jsonNodeArray->GetArrayItem(0);
616 GetContextInfo(context, jsonRoot);
617 }
618
619 return jsonRoot->ToString();
620 }
621
GetSubWindowInspector(bool isLayoutInspector)622 std::string Inspector::GetSubWindowInspector(bool isLayoutInspector)
623 {
624 auto jsonRoot = JsonUtil::Create(true);
625 jsonRoot->Put(INSPECTOR_TYPE, INSPECTOR_ROOT);
626
627 auto context = NG::PipelineContext::GetCurrentContext();
628 CHECK_NULL_RETURN(context, jsonRoot->ToString());
629 GetContextInfo(context, jsonRoot);
630 auto overlayNode = context->GetOverlayManager()->GetRootNode().Upgrade();
631 CHECK_NULL_RETURN(overlayNode, jsonRoot->ToString());
632 auto pageId = 0;
633 std::vector<RefPtr<NG::UINode>> children;
634 GetFrameNodeChildren(overlayNode, children, pageId, isLayoutInspector);
635
636 return GetInspectorInfo(children, 0, std::move(jsonRoot), isLayoutInspector);
637 }
638
FillSimplifiedInspectorAttrs(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode)639 void FillSimplifiedInspectorAttrs(const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode)
640 {
641 auto tmpJson = JsonUtil::Create(true);
642
643 InspectorFilter filter;
644 parent->ToJsonValue(tmpJson, filter);
645 jsonNode->Put(INSPECTOR_ATTR_ID, tmpJson->GetString(INSPECTOR_ATTR_ID).c_str());
646
647 auto jsonObject = JsonUtil::Create(true);
648 if (tmpJson->Contains(INSPECTOR_LABEL)) {
649 jsonObject->Put(INSPECTOR_LABEL, tmpJson->GetString(INSPECTOR_LABEL).c_str());
650 }
651 if (tmpJson->Contains(INSPECTOR_CONTENT)) {
652 jsonObject->Put(INSPECTOR_CONTENT, tmpJson->GetString(INSPECTOR_CONTENT).c_str());
653 }
654 jsonObject->Put(INSPECTOR_ENABLED, tmpJson->GetBool(INSPECTOR_ENABLED));
655 jsonObject->Put(INSPECTOR_OPACITY, tmpJson->GetDouble(INSPECTOR_OPACITY));
656 jsonObject->Put(INSPECTOR_ZINDEX, tmpJson->GetInt(INSPECTOR_ZINDEX));
657 jsonObject->Put(INSPECTOR_VISIBILITY, tmpJson->GetString(INSPECTOR_VISIBILITY).c_str());
658 jsonNode->PutRef(INSPECTOR_ATTRS, std::move(jsonObject));
659 }
660
GetSimplifiedSpanInspector(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId)661 void GetSimplifiedSpanInspector(
662 const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray, int pageId)
663 {
664 // span rect follows parent text size
665 auto spanParentNode = parent->GetParent();
666 CHECK_NULL_VOID(spanParentNode);
667 auto node = AceType::DynamicCast<FrameNode>(spanParentNode);
668 CHECK_NULL_VOID(node);
669 auto jsonNode = JsonUtil::Create(true);
670
671 FillSimplifiedInspectorAttrs(parent, jsonNode);
672
673 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
674 RectF rect = node->GetTransformRectRelativeToWindow();
675 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
676 jsonNodeArray->PutRef(std::move(jsonNode));
677 }
678
GetSimplifiedInspectorChildren(const RefPtr<NG::UINode> & parent,std::unique_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,int pageId,bool isActive)679 void GetSimplifiedInspectorChildren(
680 const RefPtr<NG::UINode>& parent, std::unique_ptr<OHOS::Ace::JsonValue>& jsonNodeArray, int pageId, bool isActive)
681 {
682 // Span is a special case in Inspector since span inherits from UINode
683 if (AceType::InstanceOf<SpanNode>(parent)) {
684 GetSimplifiedSpanInspector(parent, jsonNodeArray, pageId);
685 return;
686 }
687 auto jsonNode = JsonUtil::Create(true);
688 jsonNode->Put(INSPECTOR_TYPE, parent->GetTag().c_str());
689 auto node = AceType::DynamicCast<FrameNode>(parent);
690
691 RectF rect;
692 isActive = isActive && node->IsActive();
693 if (isActive) {
694 rect = node->GetTransformRectRelativeToWindow();
695 }
696
697 jsonNode->Put(INSPECTOR_RECT, rect.ToBounds().c_str());
698
699 FillSimplifiedInspectorAttrs(parent, jsonNode);
700
701 std::vector<RefPtr<NG::UINode>> children;
702 for (const auto& item : parent->GetChildren()) {
703 GetFrameNodeChildren(item, children, pageId);
704 }
705 auto jsonChildrenArray = JsonUtil::CreateArray(true);
706 for (auto uiNode : children) {
707 GetSimplifiedInspectorChildren(uiNode, jsonChildrenArray, pageId, isActive);
708 }
709 if (jsonChildrenArray->GetArraySize()) {
710 jsonNode->PutRef(INSPECTOR_CHILDREN, std::move(jsonChildrenArray));
711 }
712 jsonNodeArray->PutRef(std::move(jsonNode));
713 }
714
GetSimplifiedInspector(int32_t containerId)715 std::string Inspector::GetSimplifiedInspector(int32_t containerId)
716 {
717 TAG_LOGI(AceLogTag::ACE_UIEVENT, "GetSimplifiedInspector start: container %{public}d", containerId);
718 auto jsonRoot = JsonUtil::Create(true);
719 jsonRoot->Put(INSPECTOR_TYPE, INSPECTOR_ROOT);
720
721 auto context = NG::PipelineContext::GetContextByContainerId(containerId);
722 CHECK_NULL_RETURN(context, jsonRoot->ToString());
723 auto scale = context->GetViewScale();
724 auto rootHeight = context->GetRootHeight();
725 auto rootWidth = context->GetRootWidth();
726 deviceRect.SetRect(0, 0, rootWidth * scale, rootHeight * scale);
727 jsonRoot->Put(INSPECTOR_WIDTH, std::to_string(rootWidth * scale).c_str());
728 jsonRoot->Put(INSPECTOR_HEIGHT, std::to_string(rootHeight * scale).c_str());
729 jsonRoot->Put(INSPECTOR_RESOLUTION, std::to_string(SystemProperties::GetResolution()).c_str());
730
731 auto pageRootNode = context->GetStageManager()->GetLastPage();
732 CHECK_NULL_RETURN(pageRootNode, jsonRoot->ToString());
733
734 auto pagePattern = pageRootNode->GetPattern<PagePattern>();
735 CHECK_NULL_RETURN(pagePattern, jsonRoot->ToString());
736 auto pageInfo = pagePattern->GetPageInfo();
737 CHECK_NULL_RETURN(pageInfo, jsonRoot->ToString());
738 jsonRoot->Put(INSPECTOR_PAGE_URL, pageInfo->GetPageUrl().c_str());
739 jsonRoot->Put(INSPECTOR_NAV_DST_NAME, Recorder::EventRecorder::Get().GetNavDstName().c_str());
740
741 auto pageId = context->GetStageManager()->GetLastPage()->GetPageId();
742 std::vector<RefPtr<NG::UINode>> children;
743 for (const auto& item : pageRootNode->GetChildren()) {
744 GetFrameNodeChildren(item, children, pageId);
745 }
746 auto overlayNode = GetOverlayNode(pageRootNode);
747 if (overlayNode) {
748 GetFrameNodeChildren(overlayNode, children, pageId);
749 }
750 auto jsonNodeArray = JsonUtil::CreateArray(true);
751 for (auto& uiNode : children) {
752 GetSimplifiedInspectorChildren(uiNode, jsonNodeArray, pageId, true);
753 }
754 if (jsonNodeArray->GetArraySize()) {
755 jsonRoot->PutRef(INSPECTOR_CHILDREN, std::move(jsonNodeArray));
756 }
757
758 return jsonRoot->ToString();
759 }
760
SendEventByKey(const std::string & key,int action,const std::string & params)761 bool Inspector::SendEventByKey(const std::string& key, int action, const std::string& params)
762 {
763 auto context = NG::PipelineContext::GetCurrentContext();
764 CHECK_NULL_RETURN(context, false);
765 auto rootNode = context->GetRootElement();
766 CHECK_NULL_RETURN(rootNode, false);
767
768 auto inspectorElement = AceType::DynamicCast<FrameNode>(GetInspectorByKey(rootNode, key));
769 CHECK_NULL_RETURN(inspectorElement, false);
770
771 auto size = inspectorElement->GetGeometryNode()->GetFrameSize();
772 auto offset = inspectorElement->GetTransformRelativeOffset();
773 Rect rect { offset.GetX(), offset.GetY(), size.Width(), size.Height() };
774 context->GetTaskExecutor()->PostTask(
775 [weak = AceType::WeakClaim(AceType::RawPtr(context)), rect, action, params]() {
776 auto context = weak.Upgrade();
777 if (!context) {
778 return;
779 }
780 TouchEvent point;
781 point.SetX(static_cast<float>(rect.Left() + rect.Width() / 2))
782 .SetY(static_cast<float>(rect.Top() + rect.Height() / 2))
783 .SetType(TouchType::DOWN)
784 .SetTime(std::chrono::high_resolution_clock::now())
785 .SetSourceType(SourceType::TOUCH);
786 context->OnTouchEvent(point.UpdatePointers());
787
788 switch (action) {
789 case static_cast<int>(AceAction::ACTION_CLICK): {
790 context->OnTouchEvent(GetUpPoint(point).UpdatePointers());
791 break;
792 }
793 case static_cast<int>(AceAction::ACTION_LONG_CLICK): {
794 CancelableCallback<void()> inspectorTimer;
795 auto&& callback = [weak, point]() {
796 auto refPtr = weak.Upgrade();
797 if (refPtr) {
798 refPtr->OnTouchEvent(GetUpPoint(point).UpdatePointers());
799 }
800 };
801 inspectorTimer.Reset(callback);
802 auto taskExecutor =
803 SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
804 taskExecutor.PostDelayedTask(inspectorTimer, LONG_PRESS_DELAY, "ArkUIInspectorLongPressTouchEvent");
805 break;
806 }
807 default:
808 break;
809 }
810 },
811 TaskExecutor::TaskType::UI, "ArkUIInspectorSendEventByKey");
812
813 return true;
814 }
815
HideAllMenus()816 void Inspector::HideAllMenus()
817 {
818 auto context = NG::PipelineContext::GetCurrentContext();
819 CHECK_NULL_VOID(context);
820 auto overlayManager = context->GetOverlayManager();
821 CHECK_NULL_VOID(overlayManager);
822 overlayManager->HideAllMenus();
823 }
824
AddOffscreenNode(RefPtr<FrameNode> node)825 void Inspector::AddOffscreenNode(RefPtr<FrameNode> node)
826 {
827 CHECK_NULL_VOID(node);
828 offscreenNodes.insert(node);
829 }
830
RemoveOffscreenNode(RefPtr<FrameNode> node)831 void Inspector::RemoveOffscreenNode(RefPtr<FrameNode> node)
832 {
833 CHECK_NULL_VOID(node);
834 offscreenNodes.erase(node);
835 }
836
GetInspectorTree(InspectorTreeMap & treesInfo)837 void Inspector::GetInspectorTree(InspectorTreeMap& treesInfo)
838 {
839 treesInfo.clear();
840 auto context = NG::PipelineContext::GetCurrentContext();
841 CHECK_NULL_VOID(context);
842 auto stageManager = context->GetStageManager();
843 CHECK_NULL_VOID(stageManager);
844 RefPtr<UINode> pageRootNode = stageManager->GetLastPage();
845 CHECK_NULL_VOID(pageRootNode);
846 auto rootNode = AddInspectorTreeNode(pageRootNode, treesInfo);
847 CHECK_NULL_VOID(rootNode);
848 auto pageId = pageRootNode->GetPageId();
849 std::vector<RefPtr<NG::UINode>> children;
850 for (const auto& item : pageRootNode->GetChildren()) {
851 GetFrameNodeChildren(item, children, pageId, false);
852 }
853 auto overlayNode = GetOverlayNode(pageRootNode);
854 if (overlayNode) {
855 GetFrameNodeChildren(overlayNode, children, pageId, false);
856 }
857 return GetInspectorTreeInfo(children, pageId, treesInfo);
858 }
859
RecordOnePageNodes(const RefPtr<NG::UINode> & pageNode,InspectorTreeMap & treesInfo)860 void Inspector::RecordOnePageNodes(const RefPtr<NG::UINode>& pageNode, InspectorTreeMap& treesInfo)
861 {
862 CHECK_NULL_VOID(pageNode);
863 std::vector<RefPtr<NG::UINode>> children;
864 auto pageId = pageNode->GetPageId();
865 auto rootNode = AddInspectorTreeNode(pageNode, treesInfo);
866 CHECK_NULL_VOID(rootNode);
867 for (const auto& item : pageNode->GetChildren()) {
868 GetFrameNodeChildren(item, children, pageId, false);
869 }
870 auto overlayNode = GetOverlayNode(pageNode);
871 if (overlayNode) {
872 GetFrameNodeChildren(overlayNode, children, pageId, false);
873 }
874 GetInspectorTreeInfo(children, pageId, treesInfo);
875 }
876
GetRecordAllPagesNodes(InspectorTreeMap & treesInfo)877 void Inspector::GetRecordAllPagesNodes(InspectorTreeMap& treesInfo)
878 {
879 treesInfo.clear();
880 auto context = NG::PipelineContext::GetCurrentContext();
881 CHECK_NULL_VOID(context);
882 auto stageManager = context->GetStageManager();
883 CHECK_NULL_VOID(stageManager);
884 auto stageNode = stageManager->GetStageNode();
885 CHECK_NULL_VOID(stageNode);
886 for (const auto& item : stageNode->GetChildren()) {
887 auto frameNode = AceType::DynamicCast<FrameNode>(item);
888 if (frameNode == nullptr) {
889 continue;
890 }
891 auto pagePattern = frameNode->GetPattern<PagePattern>();
892 if (pagePattern == nullptr) {
893 continue;
894 }
895 RecordOnePageNodes(item, treesInfo);
896 }
897 }
898
AddInspectorTreeNode(const RefPtr<NG::UINode> & uiNode,InspectorTreeMap & recNodes)899 RefPtr<RecNode> Inspector::AddInspectorTreeNode(const RefPtr<NG::UINode>& uiNode, InspectorTreeMap& recNodes)
900 {
901 CHECK_NULL_RETURN(uiNode, nullptr);
902 RefPtr<RecNode> recNode = AceType::MakeRefPtr<RecNode>();
903 CHECK_NULL_RETURN(recNode, nullptr);
904 recNode->SetNodeId(uiNode->GetId());
905 std::string strTag = uiNode->GetTag();
906 ConvertIllegalStr(strTag);
907 recNode->SetName(strTag);
908 std::string strDebugLine = uiNode->GetDebugLine();
909 ConvertIllegalStr(strDebugLine);
910 recNode->SetDebugLine(strDebugLine);
911 auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
912 CHECK_NULL_RETURN(frameNode, nullptr);
913 auto renderContext = frameNode->GetRenderContext();
914 CHECK_NULL_RETURN(renderContext, nullptr);
915 recNode->SetSelfId(renderContext->GetNodeId());
916 recNodes.emplace(uiNode->GetId(), recNode);
917 return recNode;
918 }
919
GetInspectorTreeInfo(std::vector<RefPtr<NG::UINode>> children,int32_t pageId,InspectorTreeMap & recNodes)920 void Inspector::GetInspectorTreeInfo(
921 std::vector<RefPtr<NG::UINode>> children, int32_t pageId, InspectorTreeMap& recNodes)
922 {
923 for (auto& uiNode : children) {
924 auto addedItem = AddInspectorTreeNode(uiNode, recNodes);
925 if (addedItem == nullptr) {
926 continue;
927 }
928 GetInspectorChildrenInfo(uiNode, recNodes, pageId);
929 }
930 }
931
GetInspectorChildrenInfo(const RefPtr<NG::UINode> & parent,InspectorTreeMap & recNodes,int32_t pageId,uint32_t depth)932 void Inspector::GetInspectorChildrenInfo(
933 const RefPtr<NG::UINode>& parent, InspectorTreeMap& recNodes, int32_t pageId, uint32_t depth)
934 {
935 // Span is a special case in Inspector since span inherits from UINode
936 if (AceType::InstanceOf<SpanNode>(parent)) {
937 return;
938 }
939 if (AceType::InstanceOf<CustomNode>(parent)) {
940 return;
941 }
942 std::vector<RefPtr<NG::UINode>> children;
943 for (const auto& item : parent->GetChildren()) {
944 GetFrameNodeChildren(item, children, pageId, false);
945 }
946 auto node = AceType::DynamicCast<FrameNode>(parent);
947 if (node != nullptr) {
948 auto overlayNode = node->GetOverlayNode();
949 if (overlayNode != nullptr) {
950 GetFrameNodeChildren(overlayNode, children, pageId, false);
951 }
952 }
953 if (depth) {
954 for (auto uiNode : children) {
955 auto addedNode = AddInspectorTreeNode(uiNode, recNodes);
956 if (addedNode == nullptr) {
957 continue;
958 }
959 GetInspectorChildrenInfo(uiNode, recNodes, pageId, depth - 1);
960 }
961 }
962 }
963
GetOffScreenTreeNodes(InspectorTreeMap & nodes)964 void Inspector::GetOffScreenTreeNodes(InspectorTreeMap& nodes)
965 {
966 for (const auto& item : offscreenNodes) {
967 AddInspectorTreeNode(item, nodes);
968 }
969 }
970 } // namespace OHOS::Ace::NG
971