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