1 /*
2  * Copyright (c) 2023 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.h"
17 
18 
19 #include "event_converter.h"
20 #include "interfaces/native/event/ui_input_event_impl.h"
21 #include "node_extened.h"
22 #include "style_modifier.h"
23 
24 #include "base/error/error_code.h"
25 #include "base/utils/utils.h"
26 
27 namespace OHOS::Ace::NodeModel {
28 namespace {
29 #if defined(WINDOWS_PLATFORM)
30 #include <windows.h>
31 // Here we need to find module where GetArkUINodeAPI()
32 // function is implemented.
FindModule()33 void* FindModule()
34 {
35     // To find from main exe
36     HMODULE result = nullptr;
37     const char libname[] = "libace_compatible.dll";
38     GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, libname, &result);
39     if (result) {
40         return result;
41     }
42     TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Cannot find module!");
43     return nullptr;
44 }
FindFunction(void* library, const char* name)45 void* FindFunction(void* library, const char* name)
46 {
47     return (void*)GetProcAddress(reinterpret_cast<HMODULE>(library), name);
48 }
49 #else
50 #include <dlfcn.h>
51 void* FindModule()
52 {
53     const char libname[] = "libace_compatible.z.so";
54     void* result = dlopen(libname, RTLD_LAZY | RTLD_LOCAL);
55     if (result) {
56         return result;
57     }
58     TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Cannot load libace: %{public}s", dlerror());
59     return nullptr;
60 }
61 
62 void* FindFunction(void* library, const char* name)
63 {
64     return dlsym(library, name);
65 }
66 #endif
67 
68 ArkUIFullNodeAPI* impl = nullptr;
69 
InitialFullNodeImpl(int version)70 bool InitialFullNodeImpl(int version)
71 {
72     if (!impl) {
73         typedef ArkUIAnyAPI* (*GetAPI_t)(int);
74         GetAPI_t getAPI = nullptr;
75         void* module = FindModule();
76         if (module == nullptr) {
77             TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "fail to get module");
78             return false;
79         }
80         // Note, that RTLD_DEFAULT is ((void *) 0).
81         getAPI = reinterpret_cast<GetAPI_t>(FindFunction(module, "GetArkUIAnyFullNodeAPI"));
82         if (!getAPI) {
83             TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Cannot find GetArkUIAnyFullNodeAPI()");
84             return false;
85         }
86 
87         impl = reinterpret_cast<ArkUIFullNodeAPI*>((*getAPI)(version));
88         if (!impl) {
89             TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "getAPI() returned null");
90             return false;
91         }
92 
93         if (impl->version != version) {
94             TAG_LOGE(AceLogTag::ACE_NATIVE_NODE,
95                 "API version mismatch: expected %{public}d, but get the version %{public}d", version, impl->version);
96             return false;
97         }
98     }
99 
100     impl->getBasicAPI()->registerNodeAsyncEventReceiver(OHOS::Ace::NodeModel::HandleInnerEvent);
101     impl->getExtendedAPI()->registerCustomNodeAsyncEventReceiver(OHOS::Ace::NodeModel::HandleInnerCustomEvent);
102     return true;
103 }
104 } // namespace
105 
GetFullImpl()106 ArkUIFullNodeAPI* GetFullImpl()
107 {
108     return impl;
109 }
110 
InitialFullImpl()111 bool InitialFullImpl()
112 {
113     return InitialFullNodeImpl(ARKUI_NODE_API_VERSION);
114 }
115 
116 struct InnerEventExtraParam {
117     int32_t targetId;
118     ArkUI_NodeHandle nodePtr;
119     void* userData;
120 };
121 
122 struct ExtraData {
123     std::unordered_map<int64_t, InnerEventExtraParam*> eventMap;
124 };
125 
126 std::set<ArkUI_NodeHandle> g_nodeSet;
127 
IsValidArkUINode(ArkUI_NodeHandle nodePtr)128 bool IsValidArkUINode(ArkUI_NodeHandle nodePtr)
129 {
130     if (!nodePtr || g_nodeSet.count(nodePtr) == 0) {
131         return false;
132     }
133     return true;
134 }
135 
CreateNode(ArkUI_NodeType type)136 ArkUI_NodeHandle CreateNode(ArkUI_NodeType type)
137 {
138     static const ArkUINodeType nodes[] = { ARKUI_CUSTOM, ARKUI_TEXT, ARKUI_SPAN, ARKUI_IMAGE_SPAN, ARKUI_IMAGE,
139         ARKUI_TOGGLE, ARKUI_LOADING_PROGRESS, ARKUI_TEXT_INPUT, ARKUI_TEXTAREA, ARKUI_BUTTON, ARKUI_PROGRESS,
140         ARKUI_CHECKBOX, ARKUI_XCOMPONENT, ARKUI_DATE_PICKER, ARKUI_TIME_PICKER, ARKUI_TEXT_PICKER,
141         ARKUI_CALENDAR_PICKER, ARKUI_SLIDER, ARKUI_RADIO, ARKUI_IMAGE_ANIMATOR, ARKUI_STACK, ARKUI_SWIPER,
142         ARKUI_SCROLL, ARKUI_LIST, ARKUI_LIST_ITEM, ARKUI_LIST_ITEM_GROUP, ARKUI_COLUMN, ARKUI_ROW, ARKUI_FLEX,
143         ARKUI_REFRESH, ARKUI_WATER_FLOW, ARKUI_FLOW_ITEM, ARKUI_RELATIVE_CONTAINER, ARKUI_GRID, ARKUI_GRID_ITEM,
144         ARKUI_CUSTOM_SPAN };
145     // already check in entry point.
146     uint32_t nodeType = type < MAX_NODE_SCOPE_NUM ? type : (type - MAX_NODE_SCOPE_NUM + BASIC_COMPONENT_NUM);
147     auto* impl = GetFullImpl();
148     if (nodeType >= sizeof(nodes) / sizeof(ArkUINodeType)) {
149         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "node type: %{public}d NOT IMPLEMENT", type);
150         return nullptr;
151     }
152 
153     ArkUI_Int32 id = ARKUI_AUTO_GENERATE_NODE_ID;
154     auto* uiNode = impl->getBasicAPI()->createNode(nodes[nodeType], id, ARKUI_NODE_FLAG_C);
155     if (!uiNode) {
156         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "node type: %{public}d can not find in full impl", type);
157         return nullptr;
158     }
159     impl->getBasicAPI()->markDirty(uiNode, ARKUI_DIRTY_FLAG_ATTRIBUTE_DIFF);
160     ArkUI_Node* arkUINode = new ArkUI_Node({ type, uiNode });
161     impl->getExtendedAPI()->setAttachNodePtr(uiNode, reinterpret_cast<void*>(arkUINode));
162     g_nodeSet.emplace(arkUINode);
163     return arkUINode;
164 }
165 
DisposeNativeSource(ArkUI_NodeHandle nativePtr)166 void DisposeNativeSource(ArkUI_NodeHandle nativePtr)
167 {
168     CHECK_NULL_VOID(nativePtr);
169     if (nativePtr->customEventListeners) {
170         auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeCustomEvent*)>*>(
171         nativePtr->customEventListeners);
172         if (eventListenersSet) {
173             eventListenersSet->clear();
174         }
175         delete eventListenersSet;
176         nativePtr->customEventListeners = nullptr;
177     }
178     if (nativePtr->eventListeners) {
179         auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeEvent*)>*>(
180         nativePtr->eventListeners);
181         if (eventListenersSet) {
182             eventListenersSet->clear();
183         }
184         delete eventListenersSet;
185         nativePtr->eventListeners = nullptr;
186     }
187     if (nativePtr->areaChangeRadio) {
188         delete[] nativePtr->areaChangeRadio->value;
189         delete nativePtr->areaChangeRadio;
190         nativePtr->areaChangeRadio = nullptr;
191     }
192 }
193 
DisposeNode(ArkUI_NodeHandle nativePtr)194 void DisposeNode(ArkUI_NodeHandle nativePtr)
195 {
196     CHECK_NULL_VOID(nativePtr);
197     // already check in entry point.
198     auto* impl = GetFullImpl();
199     impl->getBasicAPI()->disposeNode(nativePtr->uiNodeHandle);
200     DisposeNativeSource(nativePtr);
201     g_nodeSet.erase(nativePtr);
202     delete nativePtr;
203     nativePtr = nullptr;
204 }
205 
AddChild(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)206 int32_t AddChild(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)
207 {
208     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
209     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
210     if (parentNode->type == -1) {
211         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
212     }
213     auto* impl = GetFullImpl();
214     // already check in entry point.
215     impl->getBasicAPI()->addChild(parentNode->uiNodeHandle, childNode->uiNodeHandle);
216     impl->getBasicAPI()->markDirty(parentNode->uiNodeHandle, ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
217     return ERROR_CODE_NO_ERROR;
218 }
219 
RemoveChild(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)220 int32_t RemoveChild(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode)
221 {
222     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
223     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
224     // already check in entry point.
225     if (parentNode->type == -1) {
226         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
227     }
228     auto* impl = GetFullImpl();
229     impl->getBasicAPI()->removeChild(parentNode->uiNodeHandle, childNode->uiNodeHandle);
230     impl->getBasicAPI()->markDirty(parentNode->uiNodeHandle, ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
231     return ERROR_CODE_NO_ERROR;
232 }
233 
InsertChildAfter(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)234 int32_t InsertChildAfter(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)
235 {
236     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
237     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
238     // already check in entry point.
239     if (parentNode->type == -1) {
240         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
241     }
242     auto* impl = GetFullImpl();
243     impl->getBasicAPI()->insertChildAfter(
244         parentNode->uiNodeHandle, childNode->uiNodeHandle, siblingNode ? siblingNode->uiNodeHandle : nullptr);
245     impl->getBasicAPI()->markDirty(parentNode->uiNodeHandle, ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
246     return ERROR_CODE_NO_ERROR;
247 }
248 
InsertChildBefore(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)249 int32_t InsertChildBefore(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, ArkUI_NodeHandle siblingNode)
250 {
251     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
252     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
253     // already check in entry point.
254     if (parentNode->type == -1) {
255         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
256     }
257     auto* impl = GetFullImpl();
258     impl->getBasicAPI()->insertChildBefore(
259         parentNode->uiNodeHandle, childNode->uiNodeHandle, siblingNode ? siblingNode->uiNodeHandle : nullptr);
260     impl->getBasicAPI()->markDirty(parentNode->uiNodeHandle, ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
261     return ERROR_CODE_NO_ERROR;
262 }
263 
InsertChildAt(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, int32_t position)264 int32_t InsertChildAt(ArkUI_NodeHandle parentNode, ArkUI_NodeHandle childNode, int32_t position)
265 {
266     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
267     CHECK_NULL_RETURN(childNode, ERROR_CODE_PARAM_INVALID);
268     // already check in entry point.
269     if (parentNode->type == -1) {
270         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
271     }
272     auto* impl = GetFullImpl();
273     impl->getBasicAPI()->insertChildAt(parentNode->uiNodeHandle, childNode->uiNodeHandle, position);
274     impl->getBasicAPI()->markDirty(parentNode->uiNodeHandle, ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST);
275     return ERROR_CODE_NO_ERROR;
276 }
277 
SetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const char* value)278 void SetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const char* value)
279 {
280     SetNodeAttribute(node, attribute, value);
281 }
282 
SetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const ArkUI_AttributeItem* value)283 int32_t SetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const ArkUI_AttributeItem* value)
284 {
285     if (node == nullptr) {
286         return ERROR_CODE_PARAM_INVALID;
287     }
288     if (node->type == -1 && attribute != NODE_LAYOUT_RECT) {
289         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
290     }
291     return SetNodeAttribute(node, attribute, value);
292 }
293 
ResetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)294 int32_t ResetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)
295 {
296     if (node == nullptr) {
297         return ERROR_CODE_PARAM_INVALID;
298     }
299     if (node->type == -1 && attribute != NODE_LAYOUT_RECT) {
300         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
301     }
302     return ResetNodeAttribute(node, attribute);
303 }
304 
GetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)305 const ArkUI_AttributeItem* GetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute)
306 {
307     if (node == nullptr) {
308         return nullptr;
309     }
310     return GetNodeAttribute(node, attribute);
311 }
312 
RegisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType, int32_t targetId)313 int32_t RegisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType, int32_t targetId)
314 {
315     return RegisterNodeEvent(nodePtr, eventType, targetId, nullptr);
316 }
317 
RegisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType, int32_t targetId, void* userData)318 int32_t RegisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType, int32_t targetId, void* userData)
319 {
320     if (nodePtr == nullptr) {
321         return ERROR_CODE_PARAM_INVALID;
322     }
323     auto originEventType = ConvertOriginEventType(eventType, nodePtr->type);
324     if (originEventType < 0) {
325         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "event is not supported %{public}d", eventType);
326         return ERROR_CODE_NATIVE_IMPL_TYPE_NOT_SUPPORTED;
327     }
328     // already check in entry point.
329     if (nodePtr->type == -1) {
330         return ERROR_CODE_NATIVE_IMPL_BUILDER_NODE_ERROR;
331     }
332     auto* impl = GetFullImpl();
333     auto* extraParam = new InnerEventExtraParam({ targetId, nodePtr, userData });
334     if (nodePtr->extraData) {
335         auto* extraData = reinterpret_cast<ExtraData*>(nodePtr->extraData);
336         auto result = extraData->eventMap.try_emplace(eventType, extraParam);
337         if (!result.second) {
338             result.first->second->targetId = targetId;
339             result.first->second->userData = userData;
340             delete extraParam;
341         }
342     } else {
343         nodePtr->extraData = new ExtraData();
344         auto* extraData = reinterpret_cast<ExtraData*>(nodePtr->extraData);
345         extraData->eventMap[eventType] = extraParam;
346     }
347     if (eventType == NODE_EVENT_ON_VISIBLE_AREA_CHANGE) {
348         ArkUI_AttributeItem* radio = nodePtr->areaChangeRadio;
349         radio = radio ? radio : static_cast<ArkUI_AttributeItem*>(userData);
350         if (!radio) {
351             return ERROR_CODE_PARAM_INVALID;
352         }
353         ArkUI_Int32 radioLength = radio->size;
354         if (radioLength <= 0) {
355             return ERROR_CODE_PARAM_INVALID;
356         }
357         ArkUI_Float32 radioList[radioLength];
358         for (int i = 0; i < radioLength; ++i) {
359             if (LessNotEqual(radio->value[i].f32, 0.0f) || GreatNotEqual(radio->value[i].f32, 1.0f)) {
360                 return ERROR_CODE_PARAM_INVALID;
361             }
362             radioList[i] = radio->value[i].f32;
363         }
364         impl->getNodeModifiers()->getCommonModifier()->setOnVisibleAreaChange(
365             nodePtr->uiNodeHandle, reinterpret_cast<int64_t>(nodePtr), radioList, radioLength);
366     } else {
367         impl->getBasicAPI()->registerNodeAsyncEvent(
368             nodePtr->uiNodeHandle, static_cast<ArkUIEventSubKind>(originEventType), reinterpret_cast<int64_t>(nodePtr));
369     }
370     return ERROR_CODE_NO_ERROR;
371 }
372 
UnregisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType)373 void UnregisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType)
374 {
375     if (nodePtr == nullptr) {
376         return;
377     }
378     if (!nodePtr->extraData) {
379         return;
380     }
381     if (nodePtr->type == -1) {
382         return;
383     }
384     auto* extraData = reinterpret_cast<ExtraData*>(nodePtr->extraData);
385     auto& eventMap = extraData->eventMap;
386     auto innerEventExtraParam = eventMap.find(eventType);
387     if (innerEventExtraParam == eventMap.end()) {
388         return;
389     }
390     delete innerEventExtraParam->second;
391     eventMap.erase(innerEventExtraParam);
392     if (eventMap.empty()) {
393         delete extraData;
394         nodePtr->extraData = nullptr;
395     }
396     auto originEventType = ConvertOriginEventType(eventType, nodePtr->type);
397     if (originEventType < 0) {
398         return;
399     }
400     impl->getBasicAPI()->unRegisterNodeAsyncEvent(
401         nodePtr->uiNodeHandle, static_cast<ArkUIEventSubKind>(originEventType));
402 }
403 
404 void (*g_compatibleEventReceiver)(ArkUI_CompatibleNodeEvent* event) = nullptr;
RegisterOnEvent(void (*eventReceiver)(ArkUI_CompatibleNodeEvent* event))405 void RegisterOnEvent(void (*eventReceiver)(ArkUI_CompatibleNodeEvent* event))
406 {
407     g_compatibleEventReceiver = eventReceiver;
408 }
409 
410 void (*g_eventReceiver)(ArkUI_NodeEvent* event) = nullptr;
RegisterOnEvent(void (*eventReceiver)(ArkUI_NodeEvent* event))411 void RegisterOnEvent(void (*eventReceiver)(ArkUI_NodeEvent* event))
412 {
413     g_eventReceiver = eventReceiver;
414 }
415 
UnregisterOnEvent()416 void UnregisterOnEvent()
417 {
418     g_eventReceiver = nullptr;
419 }
420 
HandleInnerNodeEvent(ArkUINodeEvent* innerEvent)421 void HandleInnerNodeEvent(ArkUINodeEvent* innerEvent)
422 {
423     if (!innerEvent) {
424         return;
425     }
426     auto nativeNodeEventType = GetNativeNodeEventType(innerEvent);
427     if (nativeNodeEventType == -1) {
428         return;
429     }
430     auto eventType = static_cast<ArkUI_NodeEventType>(nativeNodeEventType);
431     auto* nodePtr = reinterpret_cast<ArkUI_NodeHandle>(innerEvent->extraParam);
432     auto extraData = reinterpret_cast<ExtraData*>(nodePtr->extraData);
433     if (!extraData) {
434         return;
435     }
436     auto innerEventExtraParam = extraData->eventMap.find(eventType);
437     if (innerEventExtraParam == extraData->eventMap.end()) {
438         return;
439     }
440     ArkUI_NodeEvent event;
441     event.node = nodePtr;
442     event.eventId = innerEventExtraParam->second->targetId;
443     event.userData = innerEventExtraParam->second->userData;
444     if (!g_eventReceiver && !g_compatibleEventReceiver && (!(event.node) ||
445         (event.node && !(event.node->eventListeners)))) {
446         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "event receiver is not register");
447         return;
448     }
449     if ((g_eventReceiver || (event.node && event.node->eventListeners))  && ConvertEvent(innerEvent, &event)) {
450         event.targetId = innerEvent->nodeId;
451         ArkUI_UIInputEvent uiEvent;
452         if (eventType == NODE_TOUCH_EVENT || eventType == NODE_ON_TOUCH_INTERCEPT) {
453             uiEvent.inputType = ARKUI_UIINPUTEVENT_TYPE_TOUCH;
454             uiEvent.eventTypeId = C_TOUCH_EVENT_ID;
455             uiEvent.inputEvent = &(innerEvent->touchEvent);
456             event.origin = &uiEvent;
457         } else if (eventType == NODE_ON_MOUSE) {
458             uiEvent.inputType = ARKUI_UIINPUTEVENT_TYPE_MOUSE;
459             uiEvent.eventTypeId = C_MOUSE_EVENT_ID;
460             uiEvent.inputEvent = &(innerEvent->mouseEvent);
461             event.origin = &uiEvent;
462         } else {
463             event.origin = innerEvent;
464         }
465         HandleNodeEvent(&event);
466     }
467     if (g_compatibleEventReceiver) {
468         ArkUI_CompatibleNodeEvent event;
469         event.node = nodePtr;
470         event.eventId = innerEventExtraParam->second->targetId;
471         if (ConvertEvent(innerEvent, &event)) {
472             g_compatibleEventReceiver(&event);
473             ConvertEventResult(&event, innerEvent);
474         }
475     }
476 }
477 
GetNativeNodeEventType(ArkUINodeEvent* innerEvent)478 int32_t GetNativeNodeEventType(ArkUINodeEvent* innerEvent)
479 {
480     int32_t invalidType = -1;
481     auto* nodePtr = reinterpret_cast<ArkUI_NodeHandle>(innerEvent->extraParam);
482     if (!nodePtr || g_nodeSet.count(nodePtr) == 0) {
483         return invalidType;
484     }
485     if (!nodePtr->extraData) {
486         return invalidType;
487     }
488     auto extraData = reinterpret_cast<ExtraData*>(nodePtr->extraData);
489     ArkUIEventSubKind subKind = static_cast<ArkUIEventSubKind>(-1);
490     switch (innerEvent->kind) {
491         case COMPONENT_ASYNC_EVENT:
492             subKind = static_cast<ArkUIEventSubKind>(innerEvent->componentAsyncEvent.subKind);
493             break;
494         case TEXT_INPUT:
495             subKind = static_cast<ArkUIEventSubKind>(innerEvent->textInputEvent.subKind);
496             break;
497         case TOUCH_EVENT:
498             subKind = static_cast<ArkUIEventSubKind>(innerEvent->touchEvent.subKind);
499             break;
500         case MOUSE_INPUT_EVENT:
501             subKind = static_cast<ArkUIEventSubKind>(innerEvent->mouseEvent.subKind);
502             break;
503         case MIXED_EVENT:
504             subKind = static_cast<ArkUIEventSubKind>(innerEvent->mixedEvent.subKind);
505             break;
506         case DRAG_EVENT:
507             subKind = static_cast<ArkUIEventSubKind>(innerEvent->dragEvent.subKind);
508             break;
509         default:
510             break; /* Empty */
511     }
512     ArkUI_NodeEventType eventType = static_cast<ArkUI_NodeEventType>(ConvertToNodeEventType(subKind));
513     auto innerEventExtraParam = extraData->eventMap.find(eventType);
514     if (innerEventExtraParam == extraData->eventMap.end()) {
515         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "the event of %{public}d is not register", eventType);
516         return invalidType;
517     }
518     return static_cast<int32_t>(eventType);
519 }
520 
HandleNodeEvent(ArkUI_NodeEvent* event)521 void HandleNodeEvent(ArkUI_NodeEvent* event)
522 {
523     if (!event) {
524         return;
525     }
526     if (event->node && event->node->eventListeners) {
527         auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeEvent*)>*>(event->node->eventListeners);
528         TriggerNodeEvent(event, eventListenersSet);
529     }
530     if (g_eventReceiver) {
531         g_eventReceiver(event);
532     }
533 }
534 
TriggerNodeEvent(ArkUI_NodeEvent* event, std::set<void (*)(ArkUI_NodeEvent*)>* eventListenersSet)535 void TriggerNodeEvent(ArkUI_NodeEvent* event, std::set<void (*)(ArkUI_NodeEvent*)>* eventListenersSet)
536 {
537     if (!eventListenersSet) {
538         return;
539     }
540     if (eventListenersSet->size() == 1) {
541         auto eventListener = eventListenersSet->begin();
542         (*eventListener)(event);
543     } else if (eventListenersSet->size() > 1) {
544         for (const auto& eventListener : *eventListenersSet) {
545             (*eventListener)(event);
546             if (!IsValidArkUINode(event->node)) {
547                 break;
548             }
549         }
550     }
551 }
552 
CheckEvent(ArkUI_NodeEvent* event)553 int32_t CheckEvent(ArkUI_NodeEvent* event)
554 {
555     return 0;
556 }
557 
SetUserData(ArkUI_NodeHandle node, void* userData)558 int32_t SetUserData(ArkUI_NodeHandle node, void* userData)
559 {
560     if (!node) {
561         return ERROR_CODE_PARAM_INVALID;
562     }
563     if (!userData) {
564         return ERROR_CODE_PARAM_INVALID;
565     }
566     node->userData = userData;
567     return ERROR_CODE_NO_ERROR;
568 }
569 
GetUserData(ArkUI_NodeHandle node)570 void* GetUserData(ArkUI_NodeHandle node)
571 {
572     return node->userData;
573 }
574 
SetLengthMetricUnit(ArkUI_NodeHandle nodePtr, ArkUI_LengthMetricUnit unit)575 int32_t SetLengthMetricUnit(ArkUI_NodeHandle nodePtr, ArkUI_LengthMetricUnit unit)
576 {
577     if (!nodePtr) {
578         return ERROR_CODE_PARAM_INVALID;
579     }
580     if (!InRegion(static_cast<int32_t>(ARKUI_LENGTH_METRIC_UNIT_DEFAULT),
581         static_cast<int32_t>(ARKUI_LENGTH_METRIC_UNIT_FP), static_cast<int32_t>(unit))) {
582         return ERROR_CODE_PARAM_INVALID;
583     }
584     nodePtr->lengthMetricUnit = unit;
585     return ERROR_CODE_NO_ERROR;
586 }
587 
ApplyModifierFinish(ArkUI_NodeHandle nodePtr)588 void ApplyModifierFinish(ArkUI_NodeHandle nodePtr)
589 {
590     // already check in entry point.
591     if (!nodePtr) {
592         return;
593     }
594     auto* impl = GetFullImpl();
595     impl->getBasicAPI()->applyModifierFinish(nodePtr->uiNodeHandle);
596 }
597 
MarkDirty(ArkUI_NodeHandle nodePtr, ArkUI_NodeDirtyFlag dirtyFlag)598 void MarkDirty(ArkUI_NodeHandle nodePtr, ArkUI_NodeDirtyFlag dirtyFlag)
599 {
600     // spanNode inherited from UINode
601     if (!nodePtr) {
602         return;
603     }
604     ArkUIDirtyFlag flag = ARKUI_DIRTY_FLAG_MEASURE;
605     switch (dirtyFlag) {
606         case NODE_NEED_MEASURE: {
607             flag = ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT;
608             break;
609         }
610         case NODE_NEED_LAYOUT: {
611             flag = ARKUI_DIRTY_FLAG_LAYOUT;
612             break;
613         }
614         case NODE_NEED_RENDER: {
615             flag = ARKUI_DIRTY_FLAG_RENDER;
616             break;
617         }
618         default: {
619             flag = ARKUI_DIRTY_FLAG_MEASURE;
620         }
621     }
622     // already check in entry point.
623     auto* impl = GetFullImpl();
624     impl->getBasicAPI()->markDirty(nodePtr->uiNodeHandle, flag);
625 }
626 
AddNodeEventReceiver(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))627 int32_t AddNodeEventReceiver(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))
628 {
629     if (!nodePtr || !eventReceiver) {
630         return ERROR_CODE_PARAM_INVALID;
631     }
632     if (!nodePtr->eventListeners) {
633         nodePtr->eventListeners = new std::set<void (*)(ArkUI_NodeEvent*)>();
634     }
635     auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeEvent*)>*>(nodePtr->eventListeners);
636     if (!eventListenersSet) {
637         return ERROR_CODE_PARAM_INVALID;
638     }
639     eventListenersSet->emplace(eventReceiver);
640     return ERROR_CODE_NO_ERROR;
641 }
642 
RemoveNodeEventReceiver(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))643 int32_t RemoveNodeEventReceiver(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeEvent* event))
644 {
645     if (!nodePtr || !eventReceiver || !nodePtr->eventListeners) {
646         return ERROR_CODE_PARAM_INVALID;
647     }
648     auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeEvent*)>*>(nodePtr->eventListeners);
649     if (!eventListenersSet) {
650         return ERROR_CODE_PARAM_INVALID;
651     }
652     eventListenersSet->erase(eventReceiver);
653     if (eventListenersSet->empty()) {
654         delete eventListenersSet;
655         nodePtr->eventListeners = nullptr;
656     }
657     return ERROR_CODE_NO_ERROR;
658 }
659 
GetParseJsMedia()660 void* GetParseJsMedia()
661 {
662     void* module = FindModule();
663     if (!module) {
664         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "fail to get module");
665         return nullptr;
666     }
667     void (*parseJsMedia)(void* value, void* resource) = nullptr;
668     parseJsMedia = reinterpret_cast<void (*)(void*, void*)>(
669         FindFunction(module, "OHOS_ACE_ParseJsMedia"));
670     if (!parseJsMedia) {
671         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Cannot find OHOS_ACE_ParseJsMedia");
672         return nullptr;
673     }
674     return reinterpret_cast<void*>(parseJsMedia);
675 }
676 } // namespace OHOS::Ace::NodeModel
677 
678 #ifdef __cplusplus
679 extern "C" {
680 #endif
681 
OH_ArkUI_NodeContent_AddNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node)682 int32_t OH_ArkUI_NodeContent_AddNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node)
683 {
684     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
685     CHECK_NULL_RETURN(impl, OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND);
686     CHECK_NULL_RETURN(node, OHOS::Ace::ERROR_CODE_PARAM_INVALID);
687     return impl->getNodeModifiers()->getNodeContentModifier()->addChild(
688         reinterpret_cast<ArkUINodeContentHandle>(content), node->uiNodeHandle);
689 }
690 
OH_ArkUI_NodeContent_InsertNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node, int32_t position)691 int32_t OH_ArkUI_NodeContent_InsertNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node, int32_t position)
692 {
693     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
694     CHECK_NULL_RETURN(impl, OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND);
695     CHECK_NULL_RETURN(node, OHOS::Ace::ERROR_CODE_PARAM_INVALID);
696     return impl->getNodeModifiers()->getNodeContentModifier()->insertChild(
697         reinterpret_cast<ArkUINodeContentHandle>(content), node->uiNodeHandle, position);
698 }
699 
OH_ArkUI_NodeContent_RemoveNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node)700 int32_t OH_ArkUI_NodeContent_RemoveNode(ArkUI_NodeContentHandle content, ArkUI_NodeHandle node)
701 {
702     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
703     CHECK_NULL_RETURN(impl, OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND);
704     CHECK_NULL_RETURN(node, OHOS::Ace::ERROR_CODE_PARAM_INVALID);
705     return impl->getNodeModifiers()->getNodeContentModifier()->removeChild(
706         reinterpret_cast<ArkUINodeContentHandle>(content), node->uiNodeHandle);
707 }
708 
OH_ArkUI_NodeContent_RegisterCallback(ArkUI_NodeContentHandle content, ArkUI_NodeContentCallback callback)709 int32_t OH_ArkUI_NodeContent_RegisterCallback(ArkUI_NodeContentHandle content, ArkUI_NodeContentCallback callback)
710 {
711     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
712     CHECK_NULL_RETURN(impl, OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND);
713     auto innerCallback = reinterpret_cast<void (*)(ArkUINodeContentEvent* event)>(callback);
714     return impl->getNodeModifiers()->getNodeContentModifier()->registerEvent(
715         reinterpret_cast<ArkUINodeContentHandle>(content), nullptr, innerCallback);
716 }
717 
OH_ArkUI_NodeContentEvent_GetEventType(ArkUI_NodeContentEvent* event)718 ArkUI_NodeContentEventType OH_ArkUI_NodeContentEvent_GetEventType(ArkUI_NodeContentEvent* event)
719 {
720     CHECK_NULL_RETURN(event, static_cast<ArkUI_NodeContentEventType>(-1));
721     auto* innerEvent = reinterpret_cast<ArkUINodeContentEvent*>(event);
722     return static_cast<ArkUI_NodeContentEventType>(innerEvent->type);
723 }
724 
OH_ArkUI_NodeContentEvent_GetNodeContentHandle(ArkUI_NodeContentEvent* event)725 ArkUI_NodeContentHandle OH_ArkUI_NodeContentEvent_GetNodeContentHandle(ArkUI_NodeContentEvent* event)
726 {
727     CHECK_NULL_RETURN(event, nullptr);
728     auto* innerEvent = reinterpret_cast<ArkUINodeContentEvent*>(event);
729     return reinterpret_cast<ArkUI_NodeContentHandle>(innerEvent->nodeContent);
730 }
731 
OH_ArkUI_NodeContent_SetUserData(ArkUI_NodeContentHandle content, void* userData)732 int32_t OH_ArkUI_NodeContent_SetUserData(ArkUI_NodeContentHandle content, void* userData)
733 {
734     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
735     CHECK_NULL_RETURN(impl, OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND);
736     return impl->getNodeModifiers()->getNodeContentModifier()->setUserData(
737         reinterpret_cast<ArkUINodeContentHandle>(content), userData);
738 }
739 
OH_ArkUI_NodeContent_GetUserData(ArkUI_NodeContentHandle content)740 void* OH_ArkUI_NodeContent_GetUserData(ArkUI_NodeContentHandle content)
741 {
742     auto* impl = OHOS::Ace::NodeModel::GetFullImpl();
743     CHECK_NULL_RETURN(impl, nullptr);
744     return impl->getNodeModifiers()->getNodeContentModifier()->getUserData(
745         reinterpret_cast<ArkUINodeContentHandle>(content));
746 }
747 
748 #ifdef __cplusplus
749 };
750 #endif
751