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