• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "form_renderer.h"
17 
18 #include "configuration.h"
19 #include "form_constants.h"
20 #include "form_renderer_hilog.h"
21 #include "event_handler.h"
22 #include "refbase.h"
23 
24 #include "base/utils/utils.h"
25 
26 namespace OHOS {
27 namespace Ace {
28 namespace {
29 constexpr char FORM_RENDERER_ALLOW_UPDATE[] = "allowUpdate";
30 constexpr char FORM_RENDERER_DISPATCHER[] = "ohos.extra.param.key.process_on_form_renderer_dispatcher";
31 constexpr char FORM_RENDERER_PROCESS_ON_ADD_SURFACE[] = "ohos.extra.param.key.process_on_add_surface";
32 } // namespace
33 
34 using EventHandler = OHOS::AppExecFwk::EventHandler;
35 
FormRenderer(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime)36 FormRenderer::FormRenderer(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,
37     const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime)
38     : context_(context), runtime_(runtime)
39 {
40     HILOG_INFO("FormRenderer %{public}p created.", this);
41     if (!context_ || !runtime_) {
42         return;
43     }
44     auto& nativeEngine = (static_cast<AbilityRuntime::JsRuntime&>(*runtime_.get())).GetNativeEngine();
45     uiContent_ = UIContent::Create(context_.get(), &nativeEngine, true);
46 }
47 
InitUIContent(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)48 void FormRenderer::InitUIContent(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
49 {
50     HILOG_INFO("InitUIContent width = %{public}f , height = %{public}f.", width_, height_);
51     SetAllowUpdate(allowUpdate_);
52     uiContent_->SetFormWidth(width_);
53     uiContent_->SetFormHeight(height_);
54     uiContent_->UpdateFormSharedImage(formJsInfo.imageDataMap);
55     uiContent_->UpdateFormData(formJsInfo.formData);
56     uiContent_->Initialize(nullptr, formJsInfo.formSrc, nullptr);
57 
58     auto actionEventHandler = [weak = weak_from_this()](const std::string& action) {
59         auto formRenderer = weak.lock();
60         if (formRenderer) {
61             formRenderer->OnActionEvent(action);
62         }
63     };
64     uiContent_->SetActionEventHandler(actionEventHandler);
65 
66     auto errorEventHandler = [weak = weak_from_this()](const std::string& code, const std::string& msg) {
67         auto formRenderer = weak.lock();
68         if (formRenderer) {
69             formRenderer->OnError(code, msg);
70         }
71     };
72     uiContent_->SetErrorEventHandler(errorEventHandler);
73 
74     if (!formJsInfo.isDynamic) {
75         auto formLinkInfoUpdateHandler = [weak = weak_from_this()](const std::vector<std::string>& formLinkInfos) {
76             auto formRenderer = weak.lock();
77             if (formRenderer) {
78                 formRenderer->OnFormLinkInfoUpdate(formLinkInfos);
79             }
80         };
81         uiContent_->SetFormLinkInfoUpdateHandler(formLinkInfoUpdateHandler);
82     }
83 
84     auto rsSurfaceNode = uiContent_->GetFormRootNode();
85     if (rsSurfaceNode == nullptr) {
86         return;
87     }
88     rsSurfaceNode->SetBounds(0.0f, 0.0f, width_, height_);
89     uiContent_->Foreground();
90 }
91 
ParseWant(const OHOS::AAFwk::Want & want)92 void FormRenderer::ParseWant(const OHOS::AAFwk::Want& want)
93 {
94     allowUpdate_ = want.GetBoolParam(FORM_RENDERER_ALLOW_UPDATE, true);
95     width_ = want.GetDoubleParam(OHOS::AppExecFwk::Constants::PARAM_FORM_WIDTH_KEY, 0.0f);
96     height_ = want.GetDoubleParam(OHOS::AppExecFwk::Constants::PARAM_FORM_HEIGHT_KEY, 0.0f);
97     proxy_ = want.GetRemoteObject(FORM_RENDERER_PROCESS_ON_ADD_SURFACE);
98 }
99 
AddForm(const OHOS::AAFwk::Want & want,const OHOS::AppExecFwk::FormJsInfo & formJsInfo)100 void FormRenderer::AddForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
101 {
102     if (uiContent_ == nullptr) {
103         HILOG_ERROR("uiContent is null!");
104         return;
105     }
106     formRendererDispatcherImpl_ = new FormRendererDispatcherImpl(uiContent_, shared_from_this());
107     ParseWant(want);
108     InitUIContent(formJsInfo);
109     SetRenderDelegate(proxy_);
110     OnSurfaceCreate(formJsInfo);
111 }
112 
ReloadForm(const std::string & url)113 void FormRenderer::ReloadForm(const std::string& url)
114 {
115     if (!uiContent_) {
116         HILOG_ERROR("uiContent_ is null");
117         return;
118     }
119     uiContent_->ReloadForm(url);
120 }
121 
IsAllowUpdate()122 bool FormRenderer::IsAllowUpdate()
123 {
124     if (formRendererDispatcherImpl_ == nullptr) {
125         HILOG_ERROR("formRendererDispatcherImpl is null");
126         return true;
127     }
128 
129     return formRendererDispatcherImpl_->IsAllowUpdate();
130 }
131 
SetAllowUpdate(bool allowUpdate)132 void FormRenderer::SetAllowUpdate(bool allowUpdate)
133 {
134     if (formRendererDispatcherImpl_ == nullptr) {
135         HILOG_ERROR("formRendererDispatcherImpl is null");
136         return;
137     }
138 
139     formRendererDispatcherImpl_->SetAllowUpdate(allowUpdate);
140 }
141 
UpdateForm(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)142 void FormRenderer::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
143 {
144     if (!IsAllowUpdate()) {
145         HILOG_ERROR("Not allow update");
146         return;
147     }
148     if (!uiContent_) {
149         HILOG_ERROR("uiContent_ is null");
150         return;
151     }
152     uiContent_->UpdateFormSharedImage(formJsInfo.imageDataMap);
153     uiContent_->UpdateFormData(formJsInfo.formData);
154 }
155 
Destroy()156 void FormRenderer::Destroy()
157 {
158     HILOG_INFO("Destroy FormRenderer start.");
159     if (formRendererDelegate_ != nullptr) {
160         auto rsSurfaceNode = uiContent_->GetFormRootNode();
161         if (rsSurfaceNode != nullptr) {
162             HILOG_INFO("Form OnSurfaceRelease!");
163             formRendererDelegate_->OnSurfaceRelease(rsSurfaceNode->GetId());
164         }
165     }
166 
167     if (formRendererDelegate_ != nullptr && formRendererDelegate_->AsObject() != nullptr) {
168         formRendererDelegate_->AsObject()->RemoveDeathRecipient(renderDelegateDeathRecipient_);
169     }
170     renderDelegateDeathRecipient_ = nullptr;
171     formRendererDelegate_ = nullptr;
172     formRendererDispatcherImpl_ = nullptr;
173     if (uiContent_) {
174         uiContent_->Destroy();
175         uiContent_ = nullptr;
176     }
177     context_ = nullptr;
178     runtime_ = nullptr;
179     HILOG_INFO("Destroy FormRenderer finish.");
180 }
181 
OnSurfaceChange(float width,float height)182 void FormRenderer::OnSurfaceChange(float width, float height)
183 {
184     if (!formRendererDelegate_) {
185         HILOG_ERROR("form renderer delegate is null!");
186         return;
187     }
188     formRendererDelegate_->OnSurfaceChange(width, height);
189 }
190 
OnSurfaceCreate(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)191 void FormRenderer::OnSurfaceCreate(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
192 {
193     if (!formRendererDispatcherImpl_) {
194         HILOG_ERROR("form renderer dispatcher is null!");
195         return;
196     }
197     if (!formRendererDelegate_) {
198         HILOG_ERROR("form renderer delegate is null!");
199         return;
200     }
201     OHOS::AAFwk::Want newWant;
202     newWant.SetParam(FORM_RENDERER_DISPATCHER, formRendererDispatcherImpl_->AsObject());
203     auto rsSurfaceNode = uiContent_->GetFormRootNode();
204     HILOG_INFO("Form OnSurfaceCreate!");
205     formRendererDelegate_->OnSurfaceCreate(rsSurfaceNode, formJsInfo, newWant);
206 }
207 
OnSurfaceReuse(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)208 void FormRenderer::OnSurfaceReuse(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
209 {
210     if (!formRendererDispatcherImpl_) {
211         HILOG_ERROR("form renderer dispatcher is null!");
212         return;
213     }
214     if (!formRendererDelegate_) {
215         HILOG_ERROR("form renderer delegate is null!");
216         return;
217     }
218     auto rsSurfaceNode = uiContent_->GetFormRootNode();
219     if (rsSurfaceNode == nullptr) {
220         HILOG_ERROR("form renderer rsSurfaceNode is null!");
221         return;
222     }
223     OHOS::AAFwk::Want newWant;
224     newWant.SetParam(FORM_RENDERER_DISPATCHER, formRendererDispatcherImpl_->AsObject());
225     HILOG_INFO("Form OnSurfaceReuse.");
226     formRendererDelegate_->OnSurfaceReuse(rsSurfaceNode->GetId(), formJsInfo, newWant);
227     formRendererDelegate_->OnFormLinkInfoUpdate(cachedInfos_);
228 }
229 
OnActionEvent(const std::string & action)230 void FormRenderer::OnActionEvent(const std::string& action)
231 {
232     if (!formRendererDelegate_) {
233         HILOG_ERROR("formRendererDelegate is null!");
234         return;
235     }
236 
237     formRendererDelegate_->OnActionEvent(action);
238 }
239 
OnError(const std::string & code,const std::string & msg)240 void FormRenderer::OnError(const std::string& code, const std::string& msg)
241 {
242     if (!formRendererDelegate_) {
243         HILOG_ERROR("formRendererDelegate is null!");
244         return;
245     }
246 
247     formRendererDelegate_->OnError(code, msg);
248 }
249 
OnFormLinkInfoUpdate(const std::vector<std::string> & formLinkInfos)250 void FormRenderer::OnFormLinkInfoUpdate(const std::vector<std::string>& formLinkInfos)
251 {
252     if (!formRendererDelegate_) {
253         HILOG_ERROR("formRendererDelegate is null!");
254         return;
255     }
256     cachedInfos_ = formLinkInfos;
257     formRendererDelegate_->OnFormLinkInfoUpdate(formLinkInfos);
258 }
259 
SetRenderDelegate(const sptr<IRemoteObject> & remoteObj)260 void FormRenderer::SetRenderDelegate(const sptr<IRemoteObject>& remoteObj)
261 {
262     HILOG_INFO("Get renderRemoteObj, add death recipient.");
263     auto renderRemoteObj = iface_cast<IFormRendererDelegate>(remoteObj);
264     if (renderRemoteObj == nullptr) {
265         HILOG_ERROR("renderRemoteObj is nullptr.");
266         return;
267     }
268 
269     formRendererDelegate_ = renderRemoteObj;
270 
271     if (renderDelegateDeathRecipient_ == nullptr) {
272         renderDelegateDeathRecipient_ = new FormRenderDelegateRecipient(
273             [eventHandler = std::weak_ptr<EventHandler>(EventHandler::Current()), renderer = weak_from_this()]() {
274                 auto handler = eventHandler.lock();
275                 if (!handler) {
276                     HILOG_ERROR("eventHandler is nullptr");
277                     return;
278                 }
279 
280                 handler->PostTask([weak = renderer]() {
281                     auto formRender = weak.lock();
282                     if (!formRender) {
283                         HILOG_ERROR("formRender is nullptr");
284                         return;
285                     }
286                     formRender->ResetRenderDelegate();
287                 });
288             });
289     }
290     auto renderDelegate = formRendererDelegate_->AsObject();
291     if (renderDelegate == nullptr) {
292         HILOG_ERROR("renderDelegate is nullptr, can not get obj from renderRemoteObj.");
293         return;
294     }
295     renderDelegate->AddDeathRecipient(renderDelegateDeathRecipient_);
296 }
297 
ResetRenderDelegate()298 void FormRenderer::ResetRenderDelegate()
299 {
300     HILOG_INFO("ResetRenderDelegate.");
301     formRendererDelegate_ = nullptr;
302 }
303 
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)304 void FormRenderer::UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
305 {
306     if (!uiContent_) {
307         HILOG_ERROR("uiContent_ is null");
308         return;
309     }
310 
311     uiContent_->UpdateConfiguration(config);
312 }
313 
OnRemoteDied(const wptr<IRemoteObject> & remote)314 void FormRenderDelegateRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
315 {
316     HILOG_ERROR("Recv FormRenderDelegate death notice");
317     if (remote == nullptr) {
318         HILOG_ERROR("weak remote is null");
319         return;
320     }
321     if (handler_) {
322         handler_();
323     }
324 }
325 
AttachForm(const OHOS::AAFwk::Want & want,const OHOS::AppExecFwk::FormJsInfo & formJsInfo)326 void FormRenderer::AttachForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
327 {
328     if (uiContent_ == nullptr) {
329         HILOG_ERROR("uiContent is null!");
330         return;
331     }
332     ParseWant(want);
333     AttachUIContent(formJsInfo);
334     SetRenderDelegate(proxy_);
335     OnSurfaceReuse(formJsInfo);
336 }
337 
AttachUIContent(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)338 void FormRenderer::AttachUIContent(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
339 {
340     HILOG_INFO("AttachUIContent width = %{public}f , height = %{public}f.", width_, height_);
341     SetAllowUpdate(allowUpdate_);
342     auto rsSurfaceNode = uiContent_->GetFormRootNode();
343     if (rsSurfaceNode == nullptr) {
344         HILOG_ERROR("rsSurfaceNode is nullptr.");
345         return;
346     }
347     if (!NearEqual(width_, uiContent_->GetFormWidth()) || !NearEqual(height_, uiContent_->GetFormHeight())) {
348         uiContent_->SetFormWidth(width_);
349         uiContent_->SetFormHeight(height_);
350         uiContent_->OnFormSurfaceChange(width_, height_);
351         rsSurfaceNode->SetBounds(0.0f, 0.0f, width_, height_);
352     }
353     uiContent_->Foreground();
354 }
355 } // namespace Ace
356 } // namespace OHOS
357