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