1/* 2 * Copyright (c) 2024 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 "native_node_napi.h" 17 18 19#include "node/node_extened.h" 20#include "node/node_model.h" 21 22#include "base/error/error_code.h" 23#include "core/components_ng/base/frame_node.h" 24 25extern "C" { 26 27int32_t OH_ArkUI_GetNodeHandleFromNapiValue(napi_env env, napi_value value, ArkUI_NodeHandle* handle) 28{ 29 bool hasProperty = false; 30 auto result = napi_has_named_property(env, value, "nodePtr_", &hasProperty); 31 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 32 if (result == napi_ok && hasProperty) { 33 napi_value frameNodePtr = nullptr; 34 auto result = napi_get_named_property(env, value, "nodePtr_", &frameNodePtr); 35 if (result != napi_ok) { 36 LOGE("fail to get nodePtr"); 37 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 38 } 39 // BuilderNode case. 40 void* nativePtr = nullptr; 41 result = napi_get_value_external(env, frameNodePtr, &nativePtr); 42 if (result != napi_ok || nativePtr == nullptr) { 43 LOGE("fail to get nodePtr external value"); 44 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 45 } 46 auto* uiNodePtr = reinterpret_cast<OHOS::Ace::NG::UINode*>(nativePtr); 47 uiNodePtr->IncRefCount(); 48 *handle = new ArkUI_Node({ .type = -1, .uiNodeHandle = reinterpret_cast<ArkUINodeHandle>(nativePtr) }); 49 if (impl) { 50 impl->getExtendedAPI()->setAttachNodePtr((*handle)->uiNodeHandle, reinterpret_cast<void*>(*handle)); 51 } 52 return OHOS::Ace::ERROR_CODE_NO_ERROR; 53 } 54 result = napi_has_named_property(env, value, "builderNode_", &hasProperty); 55 if (result == napi_ok && hasProperty) { 56 // Component Content case. 57 napi_value builderNode = nullptr; 58 auto result = napi_get_named_property(env, value, "builderNode_", &builderNode); 59 if (result != napi_ok) { 60 LOGE("fail to get builderNode"); 61 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 62 } 63 napi_value nodePtr = nullptr; 64 result = napi_get_named_property(env, builderNode, "nodePtr_", &nodePtr); 65 if (result != napi_ok) { 66 LOGE("fail to get nodePtr in builderNode"); 67 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 68 } 69 void* nativePtr = nullptr; 70 result = napi_get_value_external(env, nodePtr, &nativePtr); 71 if (result != napi_ok) { 72 LOGE("fail to get nodePtr external value in builderNode"); 73 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 74 } 75 auto* uiNode = reinterpret_cast<OHOS::Ace::NG::UINode*>(nativePtr); 76 OHOS::Ace::NG::FrameNode* frameNode = OHOS::Ace::AceType::DynamicCast<OHOS::Ace::NG::FrameNode>(uiNode); 77 if (frameNode == nullptr) { 78 LOGE("fail to get frameNode value in builderNode"); 79 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 80 } 81 if (frameNode->GetTag() == "BuilderProxyNode") { 82 // need to get the really frameNode. 83 if (!impl) { 84 return OHOS::Ace::ERROR_CODE_NATIVE_IMPL_LIBRARY_NOT_FOUND; 85 } 86 auto* child = impl->getNodeModifiers()->getFrameNodeModifier()->getChild( 87 reinterpret_cast<ArkUINodeHandle>(frameNode), 0, true); 88 if (!child) { 89 LOGE("fail to get child in BuilderProxyNode"); 90 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 91 } 92 frameNode = reinterpret_cast<OHOS::Ace::NG::FrameNode*>(child); 93 } 94 frameNode->IncRefCount(); 95 *handle = new ArkUI_Node({ .type = -1, .uiNodeHandle = reinterpret_cast<ArkUINodeHandle>(frameNode) }); 96 if (impl) { 97 impl->getExtendedAPI()->setAttachNodePtr((*handle)->uiNodeHandle, reinterpret_cast<void*>(*handle)); 98 } 99 return OHOS::Ace::ERROR_CODE_NO_ERROR; 100 } 101 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 102} 103 104int32_t OH_ArkUI_GetContextFromNapiValue(napi_env env, napi_value value, ArkUI_ContextHandle* context) 105{ 106 bool hasProperty = false; 107 auto result = napi_has_named_property(env, value, "instanceId_", &hasProperty); 108 if (result != napi_ok || !hasProperty) { 109 LOGE("fail to get Context value"); 110 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 111 } 112 113 napi_value contextPtr = nullptr; 114 result = napi_get_named_property(env, value, "instanceId_", &contextPtr); 115 if (result != napi_ok) { 116 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 117 } 118 119 napi_valuetype valuetype; 120 if (napi_typeof(env, contextPtr, &valuetype) != napi_ok) { 121 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 122 } 123 if (valuetype != napi_number) { 124 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 125 } 126 int32_t instanceId = -1; 127 result = napi_get_value_int32(env, contextPtr, &instanceId); 128 if (result != napi_ok) { 129 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 130 } 131 *context = new ArkUI_Context({ .id = instanceId }); 132 return OHOS::Ace::ERROR_CODE_NO_ERROR; 133} 134 135int32_t OH_ArkUI_GetNodeContentFromNapiValue(napi_env env, napi_value value, ArkUI_NodeContentHandle* content) 136{ 137 bool hasProperty = false; 138 auto result = napi_has_named_property(env, value, "nativePtr_", &hasProperty); 139 if (result != napi_ok || !hasProperty) { 140 LOGE("fail to get native content value"); 141 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 142 } 143 napi_value nativeContent = nullptr; 144 result = napi_get_named_property(env, value, "nativePtr_", &nativeContent); 145 if (result != napi_ok) { 146 LOGE("fail to get native content"); 147 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 148 } 149 void* nativePtr = nullptr; 150 result = napi_get_value_external(env, nativeContent, &nativePtr); 151 if (result != napi_ok) { 152 LOGE("fail to get native content ptr"); 153 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 154 } 155 *content = reinterpret_cast<ArkUI_NodeContentHandle>(nativePtr); 156 return OHOS::Ace::ERROR_CODE_NO_ERROR; 157} 158 159int32_t OH_ArkUI_GetDrawableDescriptorFromNapiValue( 160 napi_env env, napi_value value, ArkUI_DrawableDescriptor** drawableDescriptor) 161{ 162 void* objectNapi = nullptr; 163 napi_unwrap(env, value, &objectNapi); 164 if (!objectNapi) { 165 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 166 } 167 ArkUI_DrawableDescriptor* drawable = 168 new ArkUI_DrawableDescriptor { nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr }; 169 auto* descriptor = reinterpret_cast<OHOS::Ace::Napi::DrawableDescriptor*>(objectNapi); 170 if (!descriptor) { 171 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 172 } 173 auto drawableType = descriptor->GetDrawableType(); 174 if (drawableType == OHOS::Ace::Napi::DrawableDescriptor::DrawableType::ANIMATED) { 175 auto* animatedDrawable = static_cast<OHOS::Ace::Napi::AnimatedDrawableDescriptor*>(descriptor); 176 if (!animatedDrawable) { 177 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 178 } 179 int32_t duration = animatedDrawable->GetDuration(); 180 int32_t iteration = animatedDrawable->GetIterations(); 181 drawable->animatedDrawableDescriptor = std::make_shared<OHOS::Ace::Napi::AnimatedDrawableDescriptor>( 182 animatedDrawable->GetPixelMapList(), duration, iteration); 183 *drawableDescriptor = drawable; 184 return OHOS::Ace::ERROR_CODE_NO_ERROR; 185 } 186 drawable->drawableDescriptor = std::make_shared<OHOS::Ace::Napi::DrawableDescriptor>(descriptor->GetPixelMap()); 187 *drawableDescriptor = drawable; 188 return OHOS::Ace::ERROR_CODE_NO_ERROR; 189} 190 191int32_t OH_ArkUI_GetDrawableDescriptorFromResourceNapiValue( 192 napi_env env, napi_value value, ArkUI_DrawableDescriptor** drawableDescriptor) 193{ 194 auto parseApi = reinterpret_cast<void (*)(void*, void*)>(OHOS::Ace::NodeModel::GetParseJsMedia()); 195 if (!parseApi) { 196 return OHOS::Ace::ERROR_CODE_PARAM_INVALID; 197 } 198 199 ArkUI_DrawableDescriptor* drawable = 200 new ArkUI_DrawableDescriptor { nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr }; 201 drawable->resource = std::make_shared<ArkUI_Resource>(); 202 parseApi(value, drawable->resource.get()); 203 *drawableDescriptor = drawable; 204 return OHOS::Ace::ERROR_CODE_NO_ERROR; 205} 206 207ArkUI_ErrorCode OH_ArkUI_GetNavigationId( 208 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 209{ 210 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 211 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 212 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 213 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 214 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 215 auto navigationAPI = fullImpl->getNavigation(); 216 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 217 auto ret = 218 navigationAPI->getNavigationId(node->uiNodeHandle, buffer, bufferSize, writeLength); 219 return static_cast<ArkUI_ErrorCode>(ret); 220} 221 222ArkUI_ErrorCode OH_ArkUI_GetNavDestinationName( 223 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 224{ 225 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 226 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 227 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 228 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 229 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 230 auto navigationAPI = fullImpl->getNavigation(); 231 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 232 auto ret = 233 navigationAPI->getNavDestinationName(node->uiNodeHandle, buffer, bufferSize, writeLength); 234 return static_cast<ArkUI_ErrorCode>(ret); 235} 236 237ArkUI_ErrorCode OH_ArkUI_GetNavStackLength(ArkUI_NodeHandle node, int32_t* length) 238{ 239 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 240 CHECK_NULL_RETURN(length, ARKUI_ERROR_CODE_PARAM_INVALID); 241 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 242 auto stacklength = fullImpl->getNavigation()->getStackLength(node->uiNodeHandle); 243 if (stacklength < 0) { 244 return ARKUI_ERROR_CODE_GET_INFO_FAILED; 245 } 246 *length = stacklength; 247 return ARKUI_ERROR_CODE_NO_ERROR; 248} 249 250ArkUI_ErrorCode OH_ArkUI_GetNavDestinationNameByIndex( 251 ArkUI_NodeHandle node, int32_t index, char* buffer, int32_t bufferSize, int32_t* writeLength) 252{ 253 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 254 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 255 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 256 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 257 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 258 auto navigationAPI = fullImpl->getNavigation(); 259 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 260 auto ret = 261 navigationAPI->getNavDesNameByIndex(node->uiNodeHandle, index, buffer, bufferSize, writeLength); 262 return static_cast<ArkUI_ErrorCode>(ret); 263} 264 265ArkUI_ErrorCode OH_ArkUI_GetNavDestinationId( 266 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 267{ 268 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 269 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 270 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 271 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 272 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 273 auto navigationAPI = fullImpl->getNavigation(); 274 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 275 auto ret = 276 navigationAPI->getNavDestinationId(node->uiNodeHandle, buffer, bufferSize, writeLength); 277 return static_cast<ArkUI_ErrorCode>(ret); 278} 279 280ArkUI_ErrorCode OH_ArkUI_GetNavDestinationState(ArkUI_NodeHandle node, ArkUI_NavDestinationState* state) 281{ 282 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 283 CHECK_NULL_RETURN(state, ARKUI_ERROR_CODE_PARAM_INVALID); 284 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 285 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 286 auto navigationAPI = fullImpl->getNavigation(); 287 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 288 289 auto navDestinationState = navigationAPI->getNavDestinationState(node->uiNodeHandle); 290 if (navDestinationState < 0) { 291 return ARKUI_ERROR_CODE_GET_INFO_FAILED; 292 } 293 *state = static_cast<ArkUI_NavDestinationState>(navDestinationState); 294 return ARKUI_ERROR_CODE_NO_ERROR; 295} 296 297ArkUI_ErrorCode OH_ArkUI_GetNavDestinationIndex(ArkUI_NodeHandle node, int32_t* index) 298{ 299 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 300 CHECK_NULL_RETURN(index, ARKUI_ERROR_CODE_PARAM_INVALID); 301 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 302 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 303 auto navigationAPI = fullImpl->getNavigation(); 304 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 305 306 auto retIndex = navigationAPI->getNavDestinationIndex(node->uiNodeHandle); 307 if (retIndex < 0) { 308 return ARKUI_ERROR_CODE_GET_INFO_FAILED; 309 } 310 *index = retIndex; 311 return ARKUI_ERROR_CODE_NO_ERROR; 312} 313 314napi_value OH_ArkUI_GetNavDestinationParam(ArkUI_NodeHandle node) 315{ 316 CHECK_NULL_RETURN(node, nullptr); 317 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 318 CHECK_NULL_RETURN(fullImpl, nullptr); 319 auto navigationAPI = fullImpl->getNavigation(); 320 CHECK_NULL_RETURN(navigationAPI, nullptr); 321 return reinterpret_cast<napi_value>(navigationAPI->getNavDestinationParam(node->uiNodeHandle)); 322} 323 324ArkUI_ErrorCode OH_ArkUI_GetRouterPageIndex(ArkUI_NodeHandle node, int32_t* index) 325{ 326 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 327 CHECK_NULL_RETURN(index, ARKUI_ERROR_CODE_PARAM_INVALID); 328 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 329 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 330 auto navigationAPI = fullImpl->getNavigation(); 331 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 332 333 auto retIndex = navigationAPI->getRouterPageIndex(node->uiNodeHandle); 334 if (retIndex < 0) { 335 return ARKUI_ERROR_CODE_GET_INFO_FAILED; 336 } 337 *index = retIndex; 338 return ARKUI_ERROR_CODE_NO_ERROR; 339} 340 341ArkUI_ErrorCode OH_ArkUI_GetRouterPageName( 342 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 343{ 344 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 345 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 346 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 347 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 348 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 349 auto navigationAPI = fullImpl->getNavigation(); 350 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 351 auto ret = 352 navigationAPI->getRouterPageName(node->uiNodeHandle, buffer, bufferSize, writeLength); 353 return static_cast<ArkUI_ErrorCode>(ret); 354} 355 356ArkUI_ErrorCode OH_ArkUI_GetRouterPagePath( 357 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 358{ 359 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 360 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 361 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 362 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 363 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 364 auto navigationAPI = fullImpl->getNavigation(); 365 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 366 auto ret = 367 navigationAPI->getRouterPagePath(node->uiNodeHandle, buffer, bufferSize, writeLength); 368 return static_cast<ArkUI_ErrorCode>(ret); 369} 370 371ArkUI_ErrorCode OH_ArkUI_GetRouterPageState(ArkUI_NodeHandle node, ArkUI_RouterPageState* state) 372{ 373 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 374 CHECK_NULL_RETURN(state, ARKUI_ERROR_CODE_PARAM_INVALID); 375 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 376 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 377 auto navigationAPI = fullImpl->getNavigation(); 378 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 379 380 auto routerPageState = navigationAPI->getRouterPageState(node->uiNodeHandle); 381 if (routerPageState < 0) { 382 return ARKUI_ERROR_CODE_GET_INFO_FAILED; 383 } 384 *state = static_cast<ArkUI_RouterPageState>(routerPageState); 385 return ARKUI_ERROR_CODE_NO_ERROR; 386} 387 388ArkUI_ErrorCode OH_ArkUI_GetRouterPageId( 389 ArkUI_NodeHandle node, char* buffer, int32_t bufferSize, int32_t* writeLength) 390{ 391 CHECK_NULL_RETURN(node, ARKUI_ERROR_CODE_PARAM_INVALID); 392 CHECK_NULL_RETURN(buffer, ARKUI_ERROR_CODE_PARAM_INVALID); 393 CHECK_NULL_RETURN(writeLength, ARKUI_ERROR_CODE_PARAM_INVALID); 394 auto* fullImpl = OHOS::Ace::NodeModel::GetFullImpl(); 395 CHECK_NULL_RETURN(fullImpl, ARKUI_ERROR_CODE_GET_INFO_FAILED); 396 auto navigationAPI = fullImpl->getNavigation(); 397 CHECK_NULL_RETURN(navigationAPI, ARKUI_ERROR_CODE_GET_INFO_FAILED); 398 auto ret = 399 navigationAPI->getRouterPageId(node->uiNodeHandle, buffer, bufferSize, writeLength); 400 return static_cast<ArkUI_ErrorCode>(ret); 401} 402} 403