1 /*
2 * Copyright (c) 2021-2022 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 "frameworks/bridge/declarative_frontend/jsview/js_plugin.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "base/log/log_wrapper.h"
21 #include "core/components/common/properties/clip_path.h"
22 #include "core/components_ng/pattern/plugin/plugin_pattern.h"
23 #include "core/components_ng/pattern/plugin/plugin_view.h"
24 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
25 #include "frameworks/core/components/box/box_component.h"
26 #include "frameworks/core/components/plugin/plugin_component.h"
27
28 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)29 void JSPlugin::Create(const JSCallbackInfo& info)
30 {
31 if (info.Length() == 0 || !info[0]->IsObject()) {
32 LOGE("plugin create fail due to PluginComponent construct param is empty or type is not Object");
33 return;
34 }
35
36 // Parse template
37 RequestPluginInfo pluginInfo;
38 auto obj = JSRef<JSObject>::Cast(info[0]);
39 auto templateObj = obj->GetProperty("template");
40 if (templateObj->IsObject()) {
41 auto jstemplateObj = JSRef<JSObject>::Cast(templateObj);
42 auto sourceVal = jstemplateObj->GetProperty("source");
43 if (sourceVal->IsString()) {
44 pluginInfo.pluginName = sourceVal->ToString();
45 }
46 auto abilityVal = jstemplateObj->GetProperty("ability");
47 if (!abilityVal->IsEmpty() && abilityVal->IsString()) {
48 pluginInfo.bundleName = abilityVal->ToString();
49 }
50
51 auto bundleValue = jstemplateObj->GetProperty("bundleName");
52 if (!bundleValue->IsEmpty() && bundleValue->IsString()) {
53 pluginInfo.bundleName = bundleValue->ToString();
54 }
55 LOGD("JSPlugin::Create: source=%{public}s bundleName=%{public}s", pluginInfo.pluginName.c_str(),
56 pluginInfo.bundleName.c_str());
57 }
58 if (pluginInfo.bundleName.size() > PATH_MAX || pluginInfo.pluginName.size() > PATH_MAX) {
59 LOGE("the source path or the bundleName is too long");
60 return;
61 }
62 // Parse data
63 auto dataValue = obj->GetProperty("data");
64
65 if (Container::IsCurrentUseNewPipeline()) {
66 NG::PluginView::Create(pluginInfo);
67 if (dataValue->IsObject()) {
68 NG::PluginView::SetData(dataValue->ToString());
69 }
70 return;
71 }
72
73 RefPtr<PluginComponent> plugin = AceType::MakeRefPtr<OHOS::Ace::PluginComponent>();
74 if (dataValue->IsObject()) {
75 plugin->SetData(dataValue->ToString());
76 }
77 plugin->SetPluginRequestInfo(pluginInfo);
78 ViewStackProcessor::GetInstance()->Push(plugin, false);
79 }
80
JsSize(const JSCallbackInfo & info)81 void JSPlugin::JsSize(const JSCallbackInfo& info)
82 {
83 if (Container::IsCurrentUseNewPipeline()) {
84 JSViewAbstract::JsSize(info);
85 return;
86 }
87 if (info.Length() == 0) {
88 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
89 return;
90 }
91
92 if (!info[0]->IsObject()) {
93 LOGE("The arg is not Object or String.");
94 return;
95 }
96
97 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
98 JSRef<JSVal> widthValue = sizeObj->GetProperty("width");
99 Dimension width = 0.0_vp;
100 if (!ParseJsDimensionVp(widthValue, width)) {
101 LOGE("ParseJsDimensionVp width is error.");
102 return;
103 }
104 JSRef<JSVal> heightValue = sizeObj->GetProperty("height");
105 Dimension height = 0.0_vp;
106 if (!ParseJsDimensionVp(heightValue, height)) {
107 LOGE("ParseJsDimensionVp height is error.");
108 return;
109 }
110
111 auto plugin = AceType::DynamicCast<PluginComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
112 if (plugin) {
113 plugin->SetPluginSize(width.IsValid() ? width : 0.0_vp, height.IsValid() ? height : 0.0_vp);
114 }
115 }
116
JsOnComplete(const JSCallbackInfo & info)117 void JSPlugin::JsOnComplete(const JSCallbackInfo& info)
118 {
119 #if defined(PLUGIN_COMPONENT_SUPPORTED)
120 if (Container::IsCurrentUseNewPipeline()) {
121 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
122 auto OnComplete = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
123 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
124 ACE_SCORING_EVENT("Plugin.OnComplete");
125 func->Execute();
126 };
127 NG::PluginView::SetOnComplete(std::move(OnComplete));
128 return;
129 }
130
131 if (info[0]->IsFunction()) {
132 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
133 auto plugin = AceType::DynamicCast<PluginComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
134
135 auto onCompleteId =
136 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
137 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
138 LOGD("onComplete send");
139 ACE_SCORING_EVENT("Plugin.onComplete");
140 func->Execute();
141 });
142 plugin->SetOnCompleteEventId(onCompleteId);
143 }
144 #endif
145 }
146
JsOnError(const JSCallbackInfo & info)147 void JSPlugin::JsOnError(const JSCallbackInfo& info)
148 {
149 #if defined(PLUGIN_COMPONENT_SUPPORTED)
150 if (Container::IsCurrentUseNewPipeline()) {
151 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
152 auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
153 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
154 ACE_SCORING_EVENT("Plugin.OnComplete");
155 std::vector<std::string> keys = { "errcode", "msg" };
156 func->Execute(keys, param);
157 };
158 NG::PluginView::SetOnError(std::move(onError));
159 return;
160 }
161
162 if (info[0]->IsFunction()) {
163 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
164 auto plugin = AceType::DynamicCast<PluginComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
165
166 auto onErrorId =
167 EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const std::string& param) {
168 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
169 std::vector<std::string> keys = { "errcode", "msg" };
170 LOGD("onError send");
171 ACE_SCORING_EVENT("Plugin.onError");
172 func->Execute(keys, param);
173 });
174
175 plugin->SetOnErrorEventId(onErrorId);
176 }
177 #endif
178 }
179
JSBind(BindingTarget globalObj)180 void JSPlugin::JSBind(BindingTarget globalObj)
181 {
182 JSClass<JSPlugin>::Declare("PluginComponent");
183 MethodOptions opt = MethodOptions::NONE;
184 JSClass<JSPlugin>::StaticMethod("create", &JSPlugin::Create, opt);
185 JSClass<JSPlugin>::StaticMethod("size", &JSPlugin::JsSize, opt);
186
187 JSClass<JSPlugin>::StaticMethod("onComplete", &JSPlugin::JsOnComplete);
188 JSClass<JSPlugin>::StaticMethod("onError", &JSPlugin::JsOnError);
189 JSClass<JSPlugin>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
190 JSClass<JSPlugin>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
191 JSClass<JSPlugin>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
192 JSClass<JSPlugin>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
193 JSClass<JSPlugin>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
194 JSClass<JSPlugin>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
195
196 JSClass<JSPlugin>::Inherit<JSViewAbstract>();
197 JSClass<JSPlugin>::Bind<>(globalObj);
198 }
199 } // namespace OHOS::Ace::Framework
200