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