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