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