1 /*
2 * Copyright (c) 2025 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_embedded_component_bridge.h"
16
17 #include "bridge/common/utils/engine_helper.h"
18 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19
20 namespace OHOS::Ace::NG {
21 constexpr int NUM_2 = 2;
SetOnTerminated(ArkUIRuntimeCallInfo * runtimeCallInfo)22 ArkUINativeModuleValue EmbeddedComponentBridge::SetOnTerminated(ArkUIRuntimeCallInfo* runtimeCallInfo)
23 {
24 EcmaVM* vm = runtimeCallInfo->GetVM();
25 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
26 if (runtimeCallInfo->GetArgsNumber() < NUM_2) {
27 return panda::NativePointerRef::New(vm, nullptr);
28 }
29 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
30 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
31 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
32 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
33 CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
34 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
35 auto nodeModifiers = GetArkUINodeModifiers();
36 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
37 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
38 nodeModifiers->getEmbeddedComponentModifier()->resetOnTerminated(nativeNode);
39 return panda::JSValueRef::Undefined(vm);
40 }
41 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
42 auto instanceId = ContainerScope::CurrentId();
43 std::function<void(int32_t, const RefPtr<WantWrap>&)> onTerminated = [vm, func = panda::CopyableGlobal(vm, func),
44 instanceId, frameNode](int32_t code,
45 const RefPtr<WantWrap>& wantWrap) {
46 panda::LocalScope pandaScope(vm);
47 panda::TryCatch trycatch(vm);
48 ContainerScope scope(instanceId);
49 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
50 auto engine = EngineHelper::GetCurrentEngine();
51 CHECK_NULL_VOID(engine);
52 NativeEngine* nativeEngine = engine->GetNativeEngine();
53 CHECK_NULL_VOID(nativeEngine);
54 auto obj = panda::ObjectRef::New(vm);
55 obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "code"), panda::NumberRef::New(vm, code));
56 if (wantWrap) {
57 auto nativeWant =
58 WantWrap::ConvertToNativeValue(wantWrap->GetWant(), reinterpret_cast<napi_env>(nativeEngine));
59 auto localRef = NapiValueToLocalValue(nativeWant);
60 obj->Set(vm, panda::StringRef::NewFromUtf8(vm, "want"), localRef);
61 }
62 panda::Local<panda::JSValueRef> params[] = { obj };
63 func->Call(vm, func.ToLocal(), params, 1);
64 };
65 nodeModifiers->getEmbeddedComponentModifier()->setOnTerminated(nativeNode, reinterpret_cast<void*>(&onTerminated));
66 return panda::JSValueRef::Undefined(vm);
67 }
68
ResetOnTerminated(ArkUIRuntimeCallInfo * runtimeCallInfo)69 ArkUINativeModuleValue EmbeddedComponentBridge::ResetOnTerminated(ArkUIRuntimeCallInfo* runtimeCallInfo)
70 {
71 EcmaVM* vm = runtimeCallInfo->GetVM();
72 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
73 if (runtimeCallInfo->GetArgsNumber() < 1) {
74 return panda::NativePointerRef::New(vm, nullptr);
75 }
76 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
77 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
78 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
79 GetArkUINodeModifiers()->getEmbeddedComponentModifier()->resetOnTerminated(nativeNode);
80 return panda::JSValueRef::Undefined(vm);
81 }
82
SetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)83 ArkUINativeModuleValue EmbeddedComponentBridge::SetOnError(ArkUIRuntimeCallInfo* runtimeCallInfo)
84 {
85 EcmaVM* vm = runtimeCallInfo->GetVM();
86 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
87 if (runtimeCallInfo->GetArgsNumber() < NUM_2) {
88 return panda::NativePointerRef::New(vm, nullptr);
89 }
90 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
91 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
92 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
93 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
94 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
95 CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
96 auto nodeModifiers = GetArkUINodeModifiers();
97 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
98 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
99 nodeModifiers->getEmbeddedComponentModifier()->resetOnError(nativeNode);
100 return panda::JSValueRef::Undefined(vm);
101 }
102 auto instanceId = ContainerScope::CurrentId();
103 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
104 std::function<void(int32_t, const std::string&, const std::string&)> onError =
105 [vm, func = panda::CopyableGlobal(vm, func), instanceId, frameNode](
106 int32_t code, const std::string& name, const std::string& message) {
107 panda::LocalScope pandaScope(vm);
108 panda::TryCatch trycatch(vm);
109 ContainerScope scope(instanceId);
110 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
111
112 const char* keys[] = { "code", "name", "message" };
113 Local<JSValueRef> values[] = { panda::NumberRef::New(vm, code),
114 panda::StringRef::NewFromUtf8(vm, name.c_str()), panda::StringRef::NewFromUtf8(vm, message.c_str()) };
115 auto onErrorObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
116 panda::Local<panda::JSValueRef> params[] = { onErrorObj };
117 func->Call(vm, func.ToLocal(), params, 1);
118 };
119 nodeModifiers->getEmbeddedComponentModifier()->setOnError(nativeNode, reinterpret_cast<void*>(&onError));
120 return panda::JSValueRef::Undefined(vm);
121 }
122
ResetOnError(ArkUIRuntimeCallInfo * runtimeCallInfo)123 ArkUINativeModuleValue EmbeddedComponentBridge::ResetOnError(ArkUIRuntimeCallInfo* runtimeCallInfo)
124 {
125 EcmaVM* vm = runtimeCallInfo->GetVM();
126 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
127 if (runtimeCallInfo->GetArgsNumber() < 1) {
128 return panda::NativePointerRef::New(vm, nullptr);
129 }
130 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
131 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
132 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
133 GetArkUINodeModifiers()->getEmbeddedComponentModifier()->resetOnError(nativeNode);
134 return panda::JSValueRef::Undefined(vm);
135 }
136 }
137