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
16 #include "js_form_edit_extension_impl.h"
17 #include "hilog_tag_wrapper.h"
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20 #include "../form_edit_extension_context/js_form_edit_extension_context.h"
21 #include "js_ui_extension_content_session.h"
22 #include "napi_common_want.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26
27 namespace {
28 constexpr size_t ARGC_ONE = 1;
29 } // namespace
30
AttachUIExtensionContext(napi_env env,void * value,void *)31 napi_value AttachUIExtensionContext(napi_env env, void *value, void *)
32 {
33 TAG_LOGD(AAFwkTag::UI_EXT, "called");
34 if (value == nullptr) {
35 TAG_LOGE(AAFwkTag::UI_EXT, "Invalid param value");
36 return nullptr;
37 }
38
39 auto ptr = reinterpret_cast<std::weak_ptr<FormEditExtensionContext> *>(value)->lock();
40 if (ptr == nullptr) {
41 TAG_LOGE(AAFwkTag::UI_EXT, "Invalid context");
42 return nullptr;
43 }
44 napi_value object = JsFormEditExtensionContext::CreateJsFormEditExtensionContext(env, ptr);
45 auto contextRef =
46 JsRuntime::LoadSystemModuleByEngine(env, "application.FormEditExtensionContext", &object, ARGC_ONE);
47 if (contextRef == nullptr) {
48 TAG_LOGE(AAFwkTag::UI_EXT, "Fail to load module");
49 return nullptr;
50 }
51 auto contextObj = contextRef->GetNapiValue();
52 if (contextObj == nullptr) {
53 TAG_LOGE(AAFwkTag::UI_EXT, "Load context error");
54 return nullptr;
55 }
56 napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachUIExtensionContext, value, nullptr);
57 auto workContext = new (std::nothrow) std::weak_ptr<FormEditExtensionContext>(ptr);
58 napi_status status = napi_wrap(
59 env, contextObj, workContext,
60 [](napi_env, void *data, void *) {
61 TAG_LOGD(AAFwkTag::UI_EXT, "Finalizer called");
62 if (data == nullptr) {
63 TAG_LOGE(AAFwkTag::UI_EXT, "Finalizer for weak_ptr is nullptr");
64 return;
65 }
66 delete static_cast<std::weak_ptr<FormEditExtensionContext> *>(data);
67 },
68 nullptr, nullptr);
69 if (status != napi_ok && workContext != nullptr) {
70 TAG_LOGE(AAFwkTag::UI_EXT, "napi_wrap Failed: %{public}d", status);
71 delete workContext;
72 return nullptr;
73 }
74
75 return contextObj;
76 }
77
JsFormEditExtensionImpl(const std::unique_ptr<Runtime> & runtime)78 JsFormEditExtensionImpl::JsFormEditExtensionImpl(const std::unique_ptr<Runtime> &runtime)
79 : JsUIExtensionBase(runtime)
80 {}
81
BindContext()82 void JsFormEditExtensionImpl::BindContext()
83 {
84 HandleScope handleScope(jsRuntime_);
85 if (jsObj_ == nullptr) {
86 return;
87 }
88 napi_env env = jsRuntime_.GetNapiEnv();
89 napi_value obj = jsObj_->GetNapiValue();
90 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
91 TAG_LOGE(AAFwkTag::UI_EXT, "obj is not object");
92 return;
93 }
94 if (context_ == nullptr) {
95 return;
96 }
97 napi_value contextObj = JsFormEditExtensionContext::CreateJsFormEditExtensionContext(env, context_);
98 if (contextObj == nullptr) {
99 TAG_LOGE(AAFwkTag::UI_EXT, "Create js ui extension context error");
100 return;
101 }
102 shellContextRef_ =
103 JsRuntime::LoadSystemModuleByEngine(env, "application.FormEditExtensionContext", &contextObj, ARGC_ONE);
104 if (shellContextRef_ == nullptr) {
105 TAG_LOGE(AAFwkTag::UI_EXT, "Fail to get loadSystemModuleByEngine");
106 return;
107 }
108 contextObj = shellContextRef_->GetNapiValue();
109 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
110 TAG_LOGE(AAFwkTag::UI_EXT, "Fail to get context native object");
111 return;
112 }
113 auto workContext = new (std::nothrow) std::shared_ptr<FormEditExtensionContext>(context_);
114 napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachUIExtensionContext, workContext,
115 nullptr);
116 context_->Bind(jsRuntime_, shellContextRef_.get());
117 napi_set_named_property(env, obj, "context", contextObj);
118 napi_status status = napi_wrap(env, contextObj, workContext,
119 [](napi_env, void *data, void *) {
120 if (data == nullptr) {
121 TAG_LOGE(AAFwkTag::UI_EXT, "Finalizer for weak_ptr is nullptr");
122 return;
123 }
124 delete static_cast<std::weak_ptr<FormEditExtensionContext> *>(data);
125 }, nullptr, nullptr);
126 if (status != napi_ok && workContext != nullptr) {
127 TAG_LOGE(AAFwkTag::UI_EXT, "napi_wrap Failed: %{public}d", status);
128 delete workContext;
129 return;
130 }
131 }
132
133 } // namespace AbilityRuntime
134 } // namespace OHOS