• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "node_model_safely.h"
17 
18 #include "base/error/error_code.h"
19 #include "base/utils/utils.h"
20 #include "node_extened.h"
21 #include "node_model.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
OH_ArkUI_PostAsyncUITask(ArkUI_ContextHandle context,void * asyncUITaskData,void (* asyncUITask)(void * asyncUITaskData),void (* onFinish)(void * asyncUITaskData))26 int32_t OH_ArkUI_PostAsyncUITask(ArkUI_ContextHandle context,
27     void* asyncUITaskData, void (*asyncUITask)(void* asyncUITaskData), void(*onFinish)(void* asyncUITaskData))
28 {
29     if (!context || !asyncUITask) {
30         return ARKUI_ERROR_CODE_PARAM_INVALID;
31     }
32     auto* contextPtr = reinterpret_cast<ArkUI_Context*>(context);
33     const auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
34     CHECK_NULL_RETURN(impl, ARKUI_ERROR_CODE_PARAM_INVALID);
35     return impl->getMultiThreadManagerAPI()->postAsyncUITask(contextPtr->id, asyncUITaskData, asyncUITask, onFinish);
36 }
37 
OH_ArkUI_PostUITask(ArkUI_ContextHandle context,void * taskData,void (* task)(void * taskData))38 int32_t OH_ArkUI_PostUITask(ArkUI_ContextHandle context, void* taskData, void(*task)(void* taskData))
39 {
40     if (!context || !task) {
41         return ARKUI_ERROR_CODE_PARAM_INVALID;
42     }
43     auto* contextPtr = reinterpret_cast<ArkUI_Context*>(context);
44     const auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
45     CHECK_NULL_RETURN(impl, ARKUI_ERROR_CODE_PARAM_INVALID);
46     return impl->getMultiThreadManagerAPI()->postUITask(contextPtr->id, taskData, task);
47 }
48 
OH_ArkUI_PostUITaskAndWait(ArkUI_ContextHandle context,void * taskData,void (* task)(void * taskData))49 int32_t OH_ArkUI_PostUITaskAndWait(ArkUI_ContextHandle context, void* taskData, void(*task)(void* taskData))
50 {
51     if (!context || !task) {
52         return ARKUI_ERROR_CODE_PARAM_INVALID;
53     }
54     auto* contextPtr = reinterpret_cast<ArkUI_Context*>(context);
55     const auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
56     CHECK_NULL_RETURN(impl, ARKUI_ERROR_CODE_PARAM_INVALID);
57     return impl->getMultiThreadManagerAPI()->postUITaskAndWait(contextPtr->id, taskData, task);
58 }
59 #ifdef __cplusplus
60 };
61 #endif
62 
63 namespace OHOS::Ace::NodeModel {
64 class ThreadSafeNodeScope {
65 public:
ThreadSafeNodeScope()66     ThreadSafeNodeScope()
67     {
68         GetFullImpl()->getMultiThreadManagerAPI()->setIsThreadSafeNodeScope(true);
69     }
70 
~ThreadSafeNodeScope()71     ~ThreadSafeNodeScope()
72     {
73         GetFullImpl()->getMultiThreadManagerAPI()->setIsThreadSafeNodeScope(false);
74     }
75 };
76 
77 std::mutex g_nodeSetMutex_;
78 std::set<ArkUI_NodeHandle> g_nodeSetSafely;
79 
CreateNodeSafely(ArkUI_NodeType type)80 ArkUI_NodeHandle CreateNodeSafely(ArkUI_NodeType type)
81 {
82     static const ArkUINodeType nodes[] = { ARKUI_CUSTOM, ARKUI_TEXT, ARKUI_SPAN, ARKUI_IMAGE_SPAN, ARKUI_IMAGE,
83         ARKUI_TOGGLE, ARKUI_LOADING_PROGRESS, ARKUI_TEXT_INPUT, ARKUI_TEXTAREA, ARKUI_BUTTON, ARKUI_PROGRESS,
84         ARKUI_CHECKBOX, ARKUI_XCOMPONENT, ARKUI_DATE_PICKER, ARKUI_TIME_PICKER, ARKUI_TEXT_PICKER,
85         ARKUI_CALENDAR_PICKER, ARKUI_SLIDER, ARKUI_RADIO, ARKUI_IMAGE_ANIMATOR, ARKUI_XCOMPONENT_TEXTURE,
86         ARKUI_CHECK_BOX_GROUP, ARKUI_STACK, ARKUI_SWIPER, ARKUI_SCROLL, ARKUI_LIST, ARKUI_LIST_ITEM,
87         ARKUI_LIST_ITEM_GROUP, ARKUI_COLUMN, ARKUI_ROW, ARKUI_FLEX, ARKUI_REFRESH, ARKUI_WATER_FLOW, ARKUI_FLOW_ITEM,
88         ARKUI_RELATIVE_CONTAINER, ARKUI_GRID, ARKUI_GRID_ITEM, ARKUI_CUSTOM_SPAN };
89     // already check in entry point.
90     uint32_t nodeType = type < MAX_NODE_SCOPE_NUM ? type : (type - MAX_NODE_SCOPE_NUM + BASIC_COMPONENT_NUM);
91     const auto* impl = GetFullImpl();
92     if (nodeType >= sizeof(nodes) / sizeof(ArkUINodeType)) {
93         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "node type: %{public}d NOT IMPLEMENT", type);
94         return nullptr;
95     }
96 
97     ArkUI_Int32 id = ARKUI_AUTO_GENERATE_NODE_ID;
98     ThreadSafeNodeScope threadSafeNodeScope;
99     auto* uiNode = impl->getBasicAPI()->createNode(nodes[nodeType], id, ARKUI_NODE_FLAG_C);
100     if (!uiNode) {
101         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "node type: %{public}d can not find in full impl", type);
102         return nullptr;
103     }
104     impl->getBasicAPI()->markDirty(uiNode, ARKUI_DIRTY_FLAG_ATTRIBUTE_DIFF);
105     ArkUI_Node* arkUINode = new ArkUI_Node({ type, uiNode, true, true });
106     impl->getExtendedAPI()->setAttachNodePtr(uiNode, reinterpret_cast<void*>(arkUINode));
107     std::lock_guard<std::mutex> lock(g_nodeSetMutex_);
108     g_nodeSetSafely.emplace(arkUINode);
109     return arkUINode;
110 }
111 
DisposeNodeSafely(ArkUI_NodeHandle nativePtr)112 void DisposeNodeSafely(ArkUI_NodeHandle nativePtr)
113 {
114     CHECK_NULL_VOID(nativePtr);
115     auto* impl = GetFullImpl();
116     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nativePtr->uiNodeHandle)) {
117         return;
118     }
119     if (!CheckIsCNode(nativePtr)) {
120         return;
121     }
122     ThreadSafeNodeScope threadSafeNodeScope;
123     impl->getBasicAPI()->disposeNode(nativePtr->uiNodeHandle);
124     DisposeNativeSource(nativePtr);
125     std::lock_guard<std::mutex> lock(g_nodeSetMutex_);
126     g_nodeSetSafely.erase(nativePtr);
127     delete nativePtr;
128     nativePtr = nullptr;
129 }
130 
AddChildSafely(ArkUI_NodeHandle parentNode,ArkUI_NodeHandle childNode)131 int32_t AddChildSafely(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)
132 {
133     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
134     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
135     auto* impl = GetFullImpl();
136     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle) ||
137         !impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(childNode->uiNodeHandle)) {
138         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
139     }
140     ThreadSafeNodeScope threadSafeNodeScope;
141     return AddChild(parentNode, childNode);
142 }
143 
RemoveChildSafely(ArkUI_NodeHandle parentNode,ArkUI_NodeHandle childNode)144 int32_t RemoveChildSafely(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)
145 {
146     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
147     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
148     auto* impl = GetFullImpl();
149     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle) ||
150         !impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(childNode->uiNodeHandle)) {
151         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
152     }
153     ThreadSafeNodeScope threadSafeNodeScope;
154     return RemoveChild(parentNode, childNode);
155 }
156 
InsertChildAfterSafely(ArkUI_NodeHandle parentNode,ArkUI_NodeHandle childNode,ArkUI_NodeHandle siblingNode)157 int32_t InsertChildAfterSafely(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)
158 {
159     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
160     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
161     auto* impl = GetFullImpl();
162     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle) ||
163         !impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(childNode->uiNodeHandle)) {
164         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
165     }
166     ThreadSafeNodeScope threadSafeNodeScope;
167     return InsertChildAfter(parentNode, childNode, siblingNode);
168 }
169 
InsertChildBeforeSafely(ArkUI_NodeHandle parentNode,ArkUI_NodeHandle childNode,ArkUI_NodeHandle siblingNode)170 int32_t InsertChildBeforeSafely(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)
171 {
172     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
173     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
174     auto* impl = GetFullImpl();
175     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle) ||
176         !impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(childNode->uiNodeHandle)) {
177         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
178     }
179     ThreadSafeNodeScope threadSafeNodeScope;
180     return InsertChildBefore(parentNode, childNode, siblingNode);
181 }
182 
InsertChildAtSafely(ArkUI_NodeHandle parentNode,ArkUI_NodeHandle childNode,int32_t position)183 int32_t InsertChildAtSafely(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, int32_t position)
184 {
185     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
186     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
187     auto* impl = GetFullImpl();
188     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle) ||
189         !impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(childNode->uiNodeHandle)) {
190         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
191     }
192     ThreadSafeNodeScope threadSafeNodeScope;
193     return InsertChildAt(parentNode, childNode, position);
194 }
195 
SetAttributeSafely(ArkUI_NodeHandle node,ArkUI_NodeAttributeType attribute,const ArkUI_AttributeItem * value)196 int32_t SetAttributeSafely(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const ArkUI_AttributeItem* value)
197 {
198     CHECK_NULL_RETURN(node, ERROR_CODE_PARAM_INVALID);
199     auto* impl = GetFullImpl();
200     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
201         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
202     }
203     ThreadSafeNodeScope threadSafeNodeScope;
204     return SetAttribute(node, attribute, value);
205 }
206 
ResetAttributeSafely(ArkUI_NodeHandle node,ArkUI_NodeAttributeType attribute)207 int32_t ResetAttributeSafely(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)
208 {
209     CHECK_NULL_RETURN(node, ERROR_CODE_PARAM_INVALID);
210     auto* impl = GetFullImpl();
211     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
212         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
213     }
214     ThreadSafeNodeScope threadSafeNodeScope;
215     return ResetAttribute(node, attribute);
216 }
217 
GetAttributeSafely(ArkUI_NodeHandle node,ArkUI_NodeAttributeType attribute)218 const ArkUI_AttributeItem* GetAttributeSafely(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)
219 {
220     CHECK_NULL_RETURN(node, nullptr);
221     auto* impl = GetFullImpl();
222     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
223         return nullptr;
224     }
225     ThreadSafeNodeScope threadSafeNodeScope;
226     return GetAttribute(node, attribute);
227 }
228 
RegisterNodeEventSafely(ArkUI_NodeHandle nodePtr,ArkUI_NodeEventType eventType,int32_t targetId,void * userData)229 int32_t RegisterNodeEventSafely(ArkUI_NodeHandle nodePtr,
230     ArkUI_NodeEventType eventType, int32_t targetId, void* userData)
231 {
232     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
233     auto* impl = GetFullImpl();
234     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
235         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
236     }
237     ThreadSafeNodeScope threadSafeNodeScope;
238     return RegisterNodeEvent(nodePtr, eventType, targetId, userData);
239 }
240 
UnregisterNodeEventSafely(ArkUI_NodeHandle nodePtr,ArkUI_NodeEventType eventType)241 void UnregisterNodeEventSafely(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType)
242 {
243     CHECK_NULL_VOID(nodePtr);
244     auto* impl = GetFullImpl();
245     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
246         return;
247     }
248     ThreadSafeNodeScope threadSafeNodeScope;
249     UnregisterNodeEvent(nodePtr, eventType);
250 }
251 
RegisterOnEventSafely(void (* eventReceiver)(ArkUI_NodeEvent * event))252 void RegisterOnEventSafely(void (*eventReceiver)(ArkUI_NodeEvent* event))
253 {
254     auto* impl = GetFullImpl();
255     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
256         RegisterOnEvent(eventReceiver);
257     }
258 }
259 
UnregisterOnEventSafely()260 void UnregisterOnEventSafely()
261 {
262     auto* impl = GetFullImpl();
263     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
264         UnregisterOnEvent();
265     }
266 }
267 
SetUserDataSafely(ArkUI_NodeHandle node,void * userData)268 int32_t SetUserDataSafely(ArkUI_NodeHandle node, void* userData)
269 {
270     CHECK_NULL_RETURN(node, ERROR_CODE_PARAM_INVALID);
271     auto* impl = GetFullImpl();
272     if (impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
273         return SetUserData(node, userData);
274     }
275     return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
276 }
277 
GetUserDataSafely(ArkUI_NodeHandle node)278 void* GetUserDataSafely(ArkUI_NodeHandle node)
279 {
280     CHECK_NULL_RETURN(node, nullptr);
281     auto* impl = GetFullImpl();
282     if (impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
283         return GetUserData(node);
284     }
285     return nullptr;
286 }
287 
SetLengthMetricUnitSafely(ArkUI_NodeHandle nodePtr,ArkUI_LengthMetricUnit unit)288 int32_t SetLengthMetricUnitSafely(ArkUI_NodeHandle nodePtr, ArkUI_LengthMetricUnit unit)
289 {
290     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
291     auto* impl = GetFullImpl();
292     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
293         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
294     }
295     ThreadSafeNodeScope threadSafeNodeScope;
296     return SetLengthMetricUnit(nodePtr, unit);
297 }
298 
MarkDirtySafely(ArkUI_NodeHandle nodePtr,ArkUI_NodeDirtyFlag dirtyFlag)299 void MarkDirtySafely(ArkUI_NodeHandle nodePtr, ArkUI_NodeDirtyFlag dirtyFlag)
300 {
301     auto* impl = GetFullImpl();
302     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
303         MarkDirty(nodePtr, dirtyFlag);
304     }
305 }
306 
AddNodeEventReceiverSafely(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeEvent * event))307 int32_t AddNodeEventReceiverSafely(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))
308 {
309     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
310     auto* impl = GetFullImpl();
311     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
312         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
313     }
314     ThreadSafeNodeScope threadSafeNodeScope;
315     return AddNodeEventReceiver(nodePtr, eventReceiver);
316 }
317 
RemoveNodeEventReceiverSafely(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeEvent * event))318 int32_t RemoveNodeEventReceiverSafely(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))
319 {
320     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
321     auto* impl = GetFullImpl();
322     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
323         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
324     }
325     ThreadSafeNodeScope threadSafeNodeScope;
326     return RemoveNodeEventReceiver(nodePtr, eventReceiver);
327 }
328 
RegisterNodeCustomEventSafely(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType,int32_t targetId,void * userData)329 int32_t RegisterNodeCustomEventSafely(ArkUI_NodeHandle node,
330     ArkUI_NodeCustomEventType eventType, int32_t targetId, void* userData)
331 {
332     CHECK_NULL_RETURN(node, ERROR_CODE_PARAM_INVALID);
333     auto* impl = GetFullImpl();
334     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
335         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
336     }
337     ThreadSafeNodeScope threadSafeNodeScope;
338     return RegisterNodeCustomEvent(node, eventType, targetId, userData);
339 }
340 
UnregisterNodeCustomEventSafely(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType)341 void UnregisterNodeCustomEventSafely(ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType)
342 {
343     CHECK_NULL_VOID(node);
344     auto* impl = GetFullImpl();
345     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
346         return;
347     }
348     ThreadSafeNodeScope threadSafeNodeScope;
349     UnregisterNodeCustomEvent(node, eventType);
350 }
351 
RegisterNodeCustomReceiverSafely(void (* eventReceiver)(ArkUI_NodeCustomEvent * event))352 void RegisterNodeCustomReceiverSafely(void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
353 {
354     auto* impl = GetFullImpl();
355     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
356         RegisterNodeCustomReceiver(eventReceiver);
357     }
358 }
359 
UnregisterNodeCustomEventReceiverSafely()360 void UnregisterNodeCustomEventReceiverSafely()
361 {
362     auto* impl = GetFullImpl();
363     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
364         UnregisterNodeCustomEventReceiver();
365     }
366 }
367 
AddNodeCustomEventReceiverSafely(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeCustomEvent * event))368 int32_t AddNodeCustomEventReceiverSafely(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
369 {
370     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
371     auto* impl = GetFullImpl();
372     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
373         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
374     }
375     ThreadSafeNodeScope threadSafeNodeScope;
376     return AddNodeCustomEventReceiver(nodePtr, eventReceiver);
377 }
378 
RemoveNodeCustomEventReceiverSafely(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeCustomEvent * event))379 int32_t RemoveNodeCustomEventReceiverSafely(ArkUI_NodeHandle nodePtr,
380     void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
381 {
382     CHECK_NULL_RETURN(nodePtr, ERROR_CODE_PARAM_INVALID);
383     auto* impl = GetFullImpl();
384     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(nodePtr->uiNodeHandle)) {
385         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
386     }
387     ThreadSafeNodeScope threadSafeNodeScope;
388     return RemoveNodeCustomEventReceiver(nodePtr, eventReceiver);
389 }
390 
SetMeasuredSizeSafely(ArkUI_NodeHandle node,int32_t width,int32_t height)391 int32_t SetMeasuredSizeSafely(ArkUI_NodeHandle node, int32_t width, int32_t height)
392 {
393     auto* impl = GetFullImpl();
394     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
395         return SetMeasuredSize(node, width, height);
396     }
397     return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
398 }
399 
SetLayoutPositionSafely(ArkUI_NodeHandle node,int32_t positionX,int32_t positionY)400 int32_t SetLayoutPositionSafely(ArkUI_NodeHandle node, int32_t positionX, int32_t positionY)
401 {
402     auto* impl = GetFullImpl();
403     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
404         return SetLayoutPosition(node, positionX, positionY);
405     }
406     return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
407 }
408 
GetMeasuredSizeSafely(ArkUI_NodeHandle node)409 ArkUI_IntSize GetMeasuredSizeSafely(ArkUI_NodeHandle node)
410 {
411     ArkUI_IntSize size;
412     auto* impl = GetFullImpl();
413     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
414         return GetMeasuredSize(node);
415     }
416     return size;
417 }
418 
GetLayoutPositionSafely(ArkUI_NodeHandle node)419 ArkUI_IntOffset GetLayoutPositionSafely(ArkUI_NodeHandle node)
420 {
421     ArkUI_IntOffset offset;
422     auto* impl = GetFullImpl();
423     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
424         return GetLayoutPosition(node);
425     }
426     return offset;
427 }
428 
MeasureNodeSafely(ArkUI_NodeHandle node,ArkUI_LayoutConstraint * constraint)429 int32_t MeasureNodeSafely(ArkUI_NodeHandle node, ArkUI_LayoutConstraint* constraint)
430 {
431     auto* impl = GetFullImpl();
432     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
433         return MeasureNode(node, constraint);
434     }
435     return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
436 }
437 
LayoutNodeSafely(ArkUI_NodeHandle node,int32_t positionX,int32_t positionY)438 int32_t LayoutNodeSafely(ArkUI_NodeHandle node, int32_t positionX, int32_t positionY)
439 {
440     auto* impl = GetFullImpl();
441     if (impl->getMultiThreadManagerAPI()->checkOnUIThread()) {
442         return LayoutNode(node, positionX, positionY);
443     }
444     return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
445 }
446 
GetTotalChildCountSafely(ArkUI_NodeHandle node)447 uint32_t GetTotalChildCountSafely(ArkUI_NodeHandle node)
448 {
449     CHECK_NULL_RETURN(node, 0);
450     auto* impl = GetFullImpl();
451     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
452         return 0;
453     }
454     ThreadSafeNodeScope threadSafeNodeScope;
455     return GetTotalChildCount(node);
456 }
457 
GetChildAtSafely(ArkUI_NodeHandle node,int32_t position)458 ArkUI_NodeHandle GetChildAtSafely(ArkUI_NodeHandle node, int32_t position)
459 {
460     CHECK_NULL_RETURN(node, nullptr);
461     auto* impl = GetFullImpl();
462     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
463         return nullptr;
464     }
465     ThreadSafeNodeScope threadSafeNodeScope;
466     return GetChildAt(node, position);
467 }
468 
GetFirstChildSafely(ArkUI_NodeHandle node)469 ArkUI_NodeHandle GetFirstChildSafely(ArkUI_NodeHandle node)
470 {
471     CHECK_NULL_RETURN(node, nullptr);
472     auto* impl = GetFullImpl();
473     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
474         return nullptr;
475     }
476     ThreadSafeNodeScope threadSafeNodeScope;
477     return GetFirstChild(node);
478 }
479 
GetLastChildSafely(ArkUI_NodeHandle node)480 ArkUI_NodeHandle GetLastChildSafely(ArkUI_NodeHandle node)
481 {
482     CHECK_NULL_RETURN(node, nullptr);
483     auto* impl = GetFullImpl();
484     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
485         return nullptr;
486     }
487     ThreadSafeNodeScope threadSafeNodeScope;
488     return GetLastChild(node);
489 }
490 
GetPreviousSiblingSafely(ArkUI_NodeHandle node)491 ArkUI_NodeHandle GetPreviousSiblingSafely(ArkUI_NodeHandle node)
492 {
493     CHECK_NULL_RETURN(node, nullptr);
494     auto* impl = GetFullImpl();
495     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
496         return nullptr;
497     }
498     ThreadSafeNodeScope threadSafeNodeScope;
499     return GetPreviousSibling(node);
500 }
501 
GetNextSiblingSafely(ArkUI_NodeHandle node)502 ArkUI_NodeHandle GetNextSiblingSafely(ArkUI_NodeHandle node)
503 {
504     CHECK_NULL_RETURN(node, nullptr);
505     auto* impl = GetFullImpl();
506     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
507         return nullptr;
508     }
509     ThreadSafeNodeScope threadSafeNodeScope;
510     return GetNextSibling(node);
511 }
512 
GetParentSafely(ArkUI_NodeHandle node)513 ArkUI_NodeHandle GetParentSafely(ArkUI_NodeHandle node)
514 {
515     CHECK_NULL_RETURN(node, nullptr);
516     auto* impl = GetFullImpl();
517     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(node->uiNodeHandle)) {
518         return nullptr;
519     }
520     ThreadSafeNodeScope threadSafeNodeScope;
521     return GetParent(node);
522 }
523 
RemoveAllChildrenSafely(ArkUI_NodeHandle parentNode)524 int32_t RemoveAllChildrenSafely(ArkUI_NodeHandle parentNode)
525 {
526     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
527     auto* impl = GetFullImpl();
528     if (!impl->getMultiThreadManagerAPI()->checkNodeOnValidThread(parentNode->uiNodeHandle)) {
529         return ERROR_CODE_NATIVE_IMPL_NODE_ON_INVALID_THREAD;
530     }
531     ThreadSafeNodeScope threadSafeNodeScope;
532     return RemoveAllChildren(parentNode);
533 }
534 
IsValidArkUINodeMultiThread(ArkUI_NodeHandle nodePtr)535 bool IsValidArkUINodeMultiThread(ArkUI_NodeHandle nodePtr)
536 {
537     std::lock_guard<std::mutex> lock(g_nodeSetMutex_);
538     return g_nodeSetSafely.count(nodePtr) > 0;
539 }
540 } // namespace OHOS::Ace::NodeModel