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