1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_node_adapter_bridge.h"
17
18 #include "jsnapi_expo.h"
19
20 #include "base/memory/ace_type.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/utils.h"
23 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h"
24 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
25 #include "core/interfaces/arkoala/arkoala_api.h"
26 #include "frameworks/core/interfaces/native/node/node_adapter_impl.h"
27
28 namespace OHOS::Ace::NG {
29
GetNodeAdapter(ArkUIRuntimeCallInfo * runtimeCallInfo)30 UINodeAdapter* GetNodeAdapter(ArkUIRuntimeCallInfo* runtimeCallInfo)
31 {
32 EcmaVM* vm = runtimeCallInfo->GetVM();
33 CHECK_NULL_RETURN(vm, nullptr);
34 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
35 CHECK_NULL_RETURN(!firstArg.IsNull(), nullptr);
36 auto* adapter = reinterpret_cast<UINodeAdapter*>(firstArg->ToNativePointer(vm)->Value());
37 return adapter;
38 }
39
SetAttachCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)40 void SetAttachCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
41 const panda::Local<panda::JSValueRef>& thisRef)
42 {
43 CHECK_NULL_VOID(adapter);
44 CHECK_NULL_VOID(!argRef->IsUndefined());
45 CHECK_NULL_VOID(argRef->IsFunction(vm));
46 auto attachObj = argRef->ToObject(vm);
47 panda::Local<panda::FunctionRef> attachFunc = attachObj;
48 auto onAttachToNode = [vm, func = JsWeak(panda::CopyableGlobal(vm, attachFunc)),
49 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))](ArkUINodeHandle node) {
50 panda::LocalScope pandaScope(vm);
51 panda::TryCatch trycatch(vm);
52 auto function = func.Lock();
53 CHECK_NULL_VOID(!function.IsEmpty());
54 CHECK_NULL_VOID(function->IsFunction(vm));
55 panda::Local<panda::JSValueRef> params[1] = { FrameNodeBridge::MakeFrameNodeInfo(vm, node) };
56 function->Call(vm, thisRef.Lock().ToLocal(), params, 1);
57 };
58 adapter->SetOnAttachToNodeFunc(std::move(onAttachToNode));
59 }
60
SetDetachCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)61 void SetDetachCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
62 const panda::Local<panda::JSValueRef>& thisRef)
63 {
64 CHECK_NULL_VOID(adapter);
65 CHECK_NULL_VOID(!argRef->IsUndefined());
66 CHECK_NULL_VOID(argRef->IsFunction(vm));
67 auto detachObj = argRef->ToObject(vm);
68 panda::Local<panda::FunctionRef> detachFunc = detachObj;
69 auto onDetachFromNode = [vm, func = JsWeak(panda::CopyableGlobal(vm, detachFunc)),
70 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))]() {
71 panda::LocalScope pandaScope(vm);
72 panda::TryCatch trycatch(vm);
73 auto function = func.Lock();
74 CHECK_NULL_VOID(!function.IsEmpty());
75 CHECK_NULL_VOID(function->IsFunction(vm));
76 function->Call(vm, thisRef.Lock().ToLocal(), {}, 0);
77 };
78 adapter->SetOnDetachFromNodeFunc(std::move(onDetachFromNode));
79 }
80
SetGetIdCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)81 void SetGetIdCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
82 const panda::Local<panda::JSValueRef>& thisRef)
83 {
84 CHECK_NULL_VOID(adapter);
85 CHECK_NULL_VOID(!argRef->IsUndefined());
86 CHECK_NULL_VOID(argRef->IsFunction(vm));
87 auto getIdObj = argRef->ToObject(vm);
88 panda::Local<panda::FunctionRef> getIdFunc = getIdObj;
89 auto onGetId = [vm, func = JsWeak(panda::CopyableGlobal(vm, getIdFunc)),
90 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))](uint32_t index) -> int32_t {
91 panda::LocalScope pandaScope(vm);
92 panda::TryCatch trycatch(vm);
93 auto function = func.Lock();
94 CHECK_NULL_RETURN(!function.IsEmpty(), index);
95 CHECK_NULL_RETURN(function->IsFunction(vm), index);
96 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, index) };
97 auto result = function->Call(vm, thisRef.Lock().ToLocal(), params, 1);
98 CHECK_NULL_RETURN(result->IsNumber(), index);
99 return result->Int32Value(vm);
100 };
101 adapter->SetOnGetChildIdFunc(std::move(onGetId));
102 }
103
SetCreateNewChildCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)104 void SetCreateNewChildCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
105 const panda::Local<panda::JSValueRef>& thisRef)
106 {
107 CHECK_NULL_VOID(adapter);
108 CHECK_NULL_VOID(!argRef->IsUndefined());
109 CHECK_NULL_VOID(argRef->IsFunction(vm));
110 auto createChildObj = argRef->ToObject(vm);
111 panda::Local<panda::FunctionRef> createChildFunc = createChildObj;
112 auto onCreateChild = [vm, func = JsWeak(panda::CopyableGlobal(vm, createChildFunc)),
113 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))](uint32_t index) -> ArkUINodeHandle {
114 panda::LocalScope pandaScope(vm);
115 panda::TryCatch trycatch(vm);
116 auto function = func.Lock();
117 CHECK_NULL_RETURN(!function.IsEmpty(), nullptr);
118 CHECK_NULL_RETURN(function->IsFunction(vm), nullptr);
119 panda::Local<panda::JSValueRef> params[1] = { panda::NumberRef::New(vm, index) };
120 auto result = function->Call(vm, thisRef.Lock().ToLocal(), params, 1);
121 CHECK_NULL_RETURN(result->IsNativePointer(vm), nullptr);
122 auto node = nodePtr(result->ToNativePointer(vm)->Value());
123 auto* currentNode = reinterpret_cast<UINode*>(node);
124 CHECK_NULL_RETURN(currentNode, node);
125 currentNode->SetNodeAdapter(true);
126 return node;
127 };
128 adapter->SetOnCreateNewChild(std::move(onCreateChild));
129 }
130
SetDisposeChildCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)131 void SetDisposeChildCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
132 const panda::Local<panda::JSValueRef>& thisRef)
133 {
134 CHECK_NULL_VOID(adapter);
135 CHECK_NULL_VOID(!argRef->IsUndefined());
136 CHECK_NULL_VOID(argRef->IsFunction(vm));
137 auto disposeChildObj = argRef->ToObject(vm);
138 panda::Local<panda::FunctionRef> disposeChildFunc = disposeChildObj;
139 auto onDisposeChild = [vm, func = JsWeak(panda::CopyableGlobal(vm, disposeChildFunc)),
140 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))](ArkUINodeHandle node, int32_t id) {
141 panda::LocalScope pandaScope(vm);
142 panda::TryCatch trycatch(vm);
143 auto function = func.Lock();
144 CHECK_NULL_VOID(!function.IsEmpty());
145 CHECK_NULL_VOID(function->IsFunction(vm));
146 panda::Local<panda::JSValueRef> params[2] = { panda::NumberRef::New(vm, id),
147 FrameNodeBridge::MakeFrameNodeInfo(vm, node) };
148 auto* currentNode = reinterpret_cast<UINode*>(node);
149 CHECK_NULL_VOID(currentNode);
150 currentNode->SetNodeAdapter(true);
151 function->Call(vm, thisRef.Lock().ToLocal(), params, 2);
152 };
153 adapter->SetOnDisposeChild(std::move(onDisposeChild));
154 }
155
SetUpdateChildCallback(EcmaVM * vm,UINodeAdapter * adapter,const panda::Local<panda::JSValueRef> & argRef,const panda::Local<panda::JSValueRef> & thisRef)156 void SetUpdateChildCallback(EcmaVM* vm, UINodeAdapter* adapter, const panda::Local<panda::JSValueRef>& argRef,
157 const panda::Local<panda::JSValueRef>& thisRef)
158 {
159 CHECK_NULL_VOID(adapter);
160 CHECK_NULL_VOID(!argRef->IsUndefined());
161 CHECK_NULL_VOID(argRef->IsFunction(vm));
162 auto updateChildObj = argRef->ToObject(vm);
163 panda::Local<panda::FunctionRef> updateChildFunc = updateChildObj;
164 auto onUpdateChild = [vm, func = JsWeak(panda::CopyableGlobal(vm, updateChildFunc)),
165 thisRef = JsWeak(panda::CopyableGlobal(vm, thisRef))](ArkUINodeHandle node, int32_t id) {
166 panda::LocalScope pandaScope(vm);
167 panda::TryCatch trycatch(vm);
168 auto function = func.Lock();
169 CHECK_NULL_VOID(!function.IsEmpty());
170 CHECK_NULL_VOID(function->IsFunction(vm));
171 panda::Local<panda::JSValueRef> params[2] = { panda::NumberRef::New(vm, id),
172 FrameNodeBridge::MakeFrameNodeInfo(vm, node) };
173 function->Call(vm, thisRef.Lock().ToLocal(), params, 2);
174 };
175 adapter->SetOnUpdateChind(std::move(onUpdateChild));
176 }
177
CreateNodeAdapter(ArkUIRuntimeCallInfo * runtimeCallInfo)178 ArkUINativeModuleValue NodeAdapterBridge::CreateNodeAdapter(ArkUIRuntimeCallInfo* runtimeCallInfo)
179 {
180 EcmaVM* vm = runtimeCallInfo->GetVM();
181 auto* handle = GetArkUIFullNodeAPI()->getNodeAdapterAPI()->create();
182 CHECK_NULL_RETURN(handle, panda::JSValueRef::Undefined(vm));
183 auto ref = AceType::MakeRefPtr<UINodeAdapter>(handle);
184 auto nativeRef = NativeUtilsBridge::CreateStrongRef(vm, ref);
185 return nativeRef;
186 }
187
SetCallbacks(ArkUIRuntimeCallInfo * runtimeCallInfo)188 ArkUINativeModuleValue NodeAdapterBridge::SetCallbacks(ArkUIRuntimeCallInfo* runtimeCallInfo)
189 {
190 EcmaVM* vm = runtimeCallInfo->GetVM();
191 auto* adapter = GetNodeAdapter(runtimeCallInfo);
192 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
193 auto thisRef = runtimeCallInfo->GetCallArgRef(1);
194 SetAttachCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(2), thisRef);
195 SetDetachCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(3), thisRef);
196 SetGetIdCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(4), thisRef);
197 SetCreateNewChildCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(5), thisRef);
198 SetDisposeChildCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(6), thisRef);
199 SetUpdateChildCallback(vm, adapter, runtimeCallInfo->GetCallArgRef(7), thisRef);
200 return panda::JSValueRef::Undefined(vm);
201 }
202
SetTotalNodeCount(ArkUIRuntimeCallInfo * runtimeCallInfo)203 ArkUINativeModuleValue NodeAdapterBridge::SetTotalNodeCount(ArkUIRuntimeCallInfo* runtimeCallInfo)
204 {
205 EcmaVM* vm = runtimeCallInfo->GetVM();
206 auto* adapter = GetNodeAdapter(runtimeCallInfo);
207 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
208 auto countArg = runtimeCallInfo->GetCallArgRef(1);
209 CHECK_NULL_RETURN(countArg->IsNumber(), panda::JSValueRef::Undefined(vm));
210 adapter->SetTotalNodeCount(countArg->Uint32Value(vm));
211 return panda::JSValueRef::Undefined(vm);
212 }
213
GetTotalNodeCount(ArkUIRuntimeCallInfo * runtimeCallInfo)214 ArkUINativeModuleValue NodeAdapterBridge::GetTotalNodeCount(ArkUIRuntimeCallInfo* runtimeCallInfo)
215 {
216 EcmaVM* vm = runtimeCallInfo->GetVM();
217 auto* adapter = GetNodeAdapter(runtimeCallInfo);
218 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
219 uint32_t count = adapter->GetTotalNodeCount();
220 return panda::NumberRef::New(vm, count);
221 }
222
NotifyItemReloaded(ArkUIRuntimeCallInfo * runtimeCallInfo)223 ArkUINativeModuleValue NodeAdapterBridge::NotifyItemReloaded(ArkUIRuntimeCallInfo* runtimeCallInfo)
224 {
225 EcmaVM* vm = runtimeCallInfo->GetVM();
226 auto* adapter = GetNodeAdapter(runtimeCallInfo);
227 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
228 adapter->NotifyItemReloaded();
229 return panda::JSValueRef::Undefined(vm);
230 }
231
NotifyItemChanged(ArkUIRuntimeCallInfo * runtimeCallInfo)232 ArkUINativeModuleValue NodeAdapterBridge::NotifyItemChanged(ArkUIRuntimeCallInfo* runtimeCallInfo)
233 {
234 EcmaVM* vm = runtimeCallInfo->GetVM();
235 auto* adapter = GetNodeAdapter(runtimeCallInfo);
236 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
237 auto startArg = runtimeCallInfo->GetCallArgRef(1);
238 CHECK_NULL_RETURN(startArg->IsNumber(), panda::JSValueRef::Undefined(vm));
239 auto countArg = runtimeCallInfo->GetCallArgRef(2);
240 CHECK_NULL_RETURN(countArg->IsNumber(), panda::JSValueRef::Undefined(vm));
241 adapter->NotifyItemChanged(startArg->Uint32Value(vm), countArg->Uint32Value(vm));
242 return panda::JSValueRef::Undefined(vm);
243 }
244
NotifyItemRemoved(ArkUIRuntimeCallInfo * runtimeCallInfo)245 ArkUINativeModuleValue NodeAdapterBridge::NotifyItemRemoved(ArkUIRuntimeCallInfo* runtimeCallInfo)
246 {
247 EcmaVM* vm = runtimeCallInfo->GetVM();
248 auto* adapter = GetNodeAdapter(runtimeCallInfo);
249 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
250 auto startArg = runtimeCallInfo->GetCallArgRef(1);
251 CHECK_NULL_RETURN(startArg->IsNumber(), panda::JSValueRef::Undefined(vm));
252 auto countArg = runtimeCallInfo->GetCallArgRef(2);
253 CHECK_NULL_RETURN(countArg->IsNumber(), panda::JSValueRef::Undefined(vm));
254 adapter->NotifyItemRemoved(startArg->Uint32Value(vm), countArg->Uint32Value(vm));
255 return panda::JSValueRef::Undefined(vm);
256 }
257
NotifyItemInserted(ArkUIRuntimeCallInfo * runtimeCallInfo)258 ArkUINativeModuleValue NodeAdapterBridge::NotifyItemInserted(ArkUIRuntimeCallInfo* runtimeCallInfo)
259 {
260 EcmaVM* vm = runtimeCallInfo->GetVM();
261 auto* adapter = GetNodeAdapter(runtimeCallInfo);
262 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
263 auto startArg = runtimeCallInfo->GetCallArgRef(1);
264 CHECK_NULL_RETURN(startArg->IsNumber(), panda::JSValueRef::Undefined(vm));
265 auto countArg = runtimeCallInfo->GetCallArgRef(2);
266 CHECK_NULL_RETURN(countArg->IsNumber(), panda::JSValueRef::Undefined(vm));
267 adapter->NotifyItemInserted(startArg->Uint32Value(vm), countArg->Uint32Value(vm));
268 return panda::JSValueRef::Undefined(vm);
269 }
270
NotifyItemMoved(ArkUIRuntimeCallInfo * runtimeCallInfo)271 ArkUINativeModuleValue NodeAdapterBridge::NotifyItemMoved(ArkUIRuntimeCallInfo* runtimeCallInfo)
272 {
273 EcmaVM* vm = runtimeCallInfo->GetVM();
274 auto* adapter = GetNodeAdapter(runtimeCallInfo);
275 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
276 auto fromArg = runtimeCallInfo->GetCallArgRef(1);
277 CHECK_NULL_RETURN(fromArg->IsNumber(), panda::JSValueRef::Undefined(vm));
278 auto toArg = runtimeCallInfo->GetCallArgRef(2);
279 CHECK_NULL_RETURN(toArg->IsNumber(), panda::JSValueRef::Undefined(vm));
280 adapter->NotifyItemMoved(fromArg->Uint32Value(vm), toArg->Uint32Value(vm));
281 return panda::JSValueRef::Undefined(vm);
282 }
283
GetAllItems(ArkUIRuntimeCallInfo * runtimeCallInfo)284 ArkUINativeModuleValue NodeAdapterBridge::GetAllItems(ArkUIRuntimeCallInfo* runtimeCallInfo)
285 {
286 EcmaVM* vm = runtimeCallInfo->GetVM();
287 auto* adapter = GetNodeAdapter(runtimeCallInfo);
288 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
289 const auto& items = adapter->GetAllItems();
290 Local<panda::ArrayRef> array = panda::ArrayRef::New(vm, items.size());
291 for (uint32_t i = 0; i < items.size(); i++) {
292 panda::ArrayRef::SetValueAt(vm, array, i, FrameNodeBridge::MakeFrameNodeInfo(vm, items[i]));
293 }
294 return array;
295 }
296
AttachNodeAdapter(ArkUIRuntimeCallInfo * runtimeCallInfo)297 ArkUINativeModuleValue NodeAdapterBridge::AttachNodeAdapter(ArkUIRuntimeCallInfo* runtimeCallInfo)
298 {
299 EcmaVM* vm = runtimeCallInfo->GetVM();
300 auto* adapter = GetNodeAdapter(runtimeCallInfo);
301 CHECK_NULL_RETURN(adapter, panda::BooleanRef::New(vm, false));
302 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(1);
303 CHECK_NULL_RETURN(!nodeArg.IsNull(), panda::BooleanRef::New(vm, false));
304 auto* frameNode = reinterpret_cast<FrameNode*>(nodeArg->ToNativePointer(vm)->Value());
305 CHECK_NULL_RETURN(frameNode, panda::BooleanRef::New(vm, false));
306 auto* nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
307 bool ret = GetArkUIFullNodeAPI()->getNodeAdapterAPI()->attachHostNode(adapter->GetHandle(), nativeNode);
308 return panda::BooleanRef::New(vm, ret);
309 }
310
DetachNodeAdapter(ArkUIRuntimeCallInfo * runtimeCallInfo)311 ArkUINativeModuleValue NodeAdapterBridge::DetachNodeAdapter(ArkUIRuntimeCallInfo* runtimeCallInfo)
312 {
313 EcmaVM* vm = runtimeCallInfo->GetVM();
314 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
315 CHECK_NULL_RETURN(!nodeArg.IsNull(), panda::JSValueRef::Undefined(vm));
316 auto* nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
317 GetArkUIFullNodeAPI()->getNodeAdapterAPI()->detachHostNode(nativeNode);
318 GetArkUIFullNodeAPI()->getBasicAPI()->markDirty(nativeNode, ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT);
319 return panda::JSValueRef::Undefined(vm);
320 }
321
FireArkUIObjectLifecycleCallback(ArkUIRuntimeCallInfo * runtimeCallInfo)322 ArkUINativeModuleValue NodeAdapterBridge::FireArkUIObjectLifecycleCallback(ArkUIRuntimeCallInfo* runtimeCallInfo)
323 {
324 EcmaVM* vm = runtimeCallInfo->GetVM();
325 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
326 Local<JSValueRef> arg = runtimeCallInfo->GetCallArgRef(3);
327 CHECK_NULL_RETURN(!arg.IsNull(), panda::JSValueRef::Undefined(vm));
328 auto* adapter = reinterpret_cast<UINodeAdapter*>(arg->ToNativePointer(vm)->Value());
329 CHECK_NULL_RETURN(adapter, panda::JSValueRef::Undefined(vm));
330 void* data = static_cast<void*>(runtimeCallInfo);
331 GetArkUIFullNodeAPI()->getNodeAdapterAPI()->fireArkUIObjectLifecycleCallback(data, adapter->GetHandle());
332 return panda::JSValueRef::Undefined(vm);
333 }
334
GetNodeType(ArkUIRuntimeCallInfo * runtimeCallInfo)335 ArkUINativeModuleValue NodeAdapterBridge::GetNodeType(ArkUIRuntimeCallInfo* runtimeCallInfo)
336 {
337 EcmaVM* vm = runtimeCallInfo->GetVM();
338 auto* adapter = GetNodeAdapter(runtimeCallInfo);
339 CHECK_NULL_RETURN(adapter, panda::StringRef::NewFromUtf8(vm, ""));
340 auto nodeType = GetArkUIFullNodeAPI()->getNodeAdapterAPI()->getNodeType(adapter->GetHandle());
341 return panda::StringRef::NewFromUtf8(vm, nodeType);
342 }
343 } // namespace OHOS::Ace::NG
344