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