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