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 27namespace OHOS::Ace::NodeModel { 28namespace { 29#if defined(WINDOWS_PLATFORM) 30#include <windows.h> 31// Here we need to find module where GetArkUINodeAPI() 32// function is implemented. 33void* 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} 45void* FindFunction(void* library, const char* name) 46{ 47 return (void*)GetProcAddress(reinterpret_cast<HMODULE>(library), name); 48} 49#else 50#include <dlfcn.h> 51void* 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 62void* FindFunction(void* library, const char* name) 63{ 64 return dlsym(library, name); 65} 66#endif 67 68ArkUIFullNodeAPI* impl = nullptr; 69 70bool 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 106ArkUIFullNodeAPI* GetFullImpl() 107{ 108 return impl; 109} 110 111bool InitialFullImpl() 112{ 113 return InitialFullNodeImpl(ARKUI_NODE_API_VERSION); 114} 115 116struct InnerEventExtraParam { 117 int32_t targetId; 118 ArkUI_NodeHandle nodePtr; 119 void* userData; 120}; 121 122struct ExtraData { 123 std::unordered_map<int64_t, InnerEventExtraParam*> eventMap; 124}; 125 126std::set<ArkUI_NodeHandle> g_nodeSet; 127 128bool IsValidArkUINode(ArkUI_NodeHandle nodePtr) 129{ 130 if (!nodePtr || g_nodeSet.count(nodePtr) == 0) { 131 return false; 132 } 133 return true; 134} 135 136ArkUI_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 166void 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 194void 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 206int32_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 220int32_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 234int32_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 249int32_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 264int32_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 278void SetAttribute(ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const char* value) 279{ 280 SetNodeAttribute(node, attribute, value); 281} 282 283int32_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 294int32_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 305const 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 313int32_t RegisterNodeEvent(ArkUI_NodeHandle nodePtr, ArkUI_NodeEventType eventType, int32_t targetId) 314{ 315 return RegisterNodeEvent(nodePtr, eventType, targetId, nullptr); 316} 317 318int32_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 373void 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 404void (*g_compatibleEventReceiver)(ArkUI_CompatibleNodeEvent* event) = nullptr; 405void RegisterOnEvent(void (*eventReceiver)(ArkUI_CompatibleNodeEvent* event)) 406{ 407 g_compatibleEventReceiver = eventReceiver; 408} 409 410void (*g_eventReceiver)(ArkUI_NodeEvent* event) = nullptr; 411void RegisterOnEvent(void (*eventReceiver)(ArkUI_NodeEvent* event)) 412{ 413 g_eventReceiver = eventReceiver; 414} 415 416void UnregisterOnEvent() 417{ 418 g_eventReceiver = nullptr; 419} 420 421void 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 478int32_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 521void 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 535void 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 553int32_t CheckEvent(ArkUI_NodeEvent* event) 554{ 555 return 0; 556} 557 558int32_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 570void* GetUserData(ArkUI_NodeHandle node) 571{ 572 return node->userData; 573} 574 575int32_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 588void 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 598void 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 627int32_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 643int32_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 660void* 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 679extern "C" { 680#endif 681 682int32_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 691int32_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 700int32_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 709int32_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 718ArkUI_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 725ArkUI_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 732int32_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 740void* 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