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_group.h"
17
18 #include "form_renderer.h"
19 #include "form_renderer_hilog.h"
20 #include "form_renderer_event_report.h"
21
22 namespace OHOS {
23 namespace Ace {
24 namespace {
25 constexpr char FORM_RENDERER_COMP_ID[] = "ohos.extra.param.key.form_comp_id";
26 constexpr char FORM_RENDER_STATE[] = "ohos.extra.param.key.form_render_state";
27 }
Create(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime,std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)28 std::shared_ptr<FormRendererGroup> FormRendererGroup::Create(
29 const std::shared_ptr<OHOS::AbilityRuntime::Context> context,
30 const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime,
31 std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)
32 {
33 return std::make_shared<FormRendererGroup>(context, runtime, eventHandler);
34 }
35
FormRendererGroup(const std::shared_ptr<OHOS::AbilityRuntime::Context> context,const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime,std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)36 FormRendererGroup::FormRendererGroup(
37 const std::shared_ptr<OHOS::AbilityRuntime::Context> context,
38 const std::shared_ptr<OHOS::AbilityRuntime::Runtime> runtime,
39 std::weak_ptr<OHOS::AppExecFwk::EventHandler> eventHandler)
40 : context_(context), runtime_(runtime), eventHandler_(eventHandler) {}
41
~FormRendererGroup()42 FormRendererGroup::~FormRendererGroup()
43 {
44 DeleteForm();
45 }
46
AddForm(const OHOS::AAFwk::Want & want,const OHOS::AppExecFwk::FormJsInfo & formJsInfo)47 void FormRendererGroup::AddForm(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
48 {
49 auto compId = want.GetStringParam(FORM_RENDERER_COMP_ID);
50 currentCompId_ = compId;
51 FormRequest formRequest;
52 formRequest.compId = compId;
53 formRequest.want = want;
54 formRequest.formJsInfo = formJsInfo;
55 auto info = std::find_if(
56 formRequests_.begin(), formRequests_.end(), formRequest);
57 if (info != formRequests_.end()) {
58 *info = formRequest;
59 } else {
60 formRequests_.emplace_back(formRequest);
61 }
62 bool isVerified = want.GetBoolParam(FORM_RENDER_STATE, false);
63 if (isVerified) {
64 HILOG_DEBUG("The user is verified, start rendering form.");
65 InnerAddForm(formRequest);
66 return;
67 }
68 HILOG_INFO("The user is not verified at this time, can not render the form now.");
69 PreInitAddForm(formRequest);
70 }
71
PreInitAddForm(const FormRequest & formRequest)72 void FormRendererGroup::PreInitAddForm(const FormRequest& formRequest)
73 {
74 HILOG_DEBUG("called");
75 if (initState_ != FormRendererInitState::UNINITIALIZED) {
76 HILOG_WARN("no need to pre init again");
77 return;
78 }
79 auto compId = formRequest.compId;
80 OHOS::AAFwk::Want want = formRequest.want;
81 AppExecFwk::FormJsInfo formJsInfo = formRequest.formJsInfo;
82 if (formRenderer_ != nullptr) {
83 HILOG_WARN("no need to pre init");
84 return;
85 }
86 formRenderer_ = std::make_shared<FormRenderer>(context_, runtime_, eventHandler_);
87 if (!formRenderer_) {
88 HILOG_ERROR("create form render failed");
89 return;
90 }
91 HILOG_INFO("compId is %{public}s. formId is %{public}s", compId.c_str(),
92 std::to_string(formJsInfo.formId).c_str());
93 formRenderer_->PreInitAddForm(want, formJsInfo);
94 initState_ = FormRendererInitState::PRE_INITIALIZED;
95 }
96
OnUnlock()97 void FormRendererGroup::OnUnlock()
98 {
99 HILOG_INFO("The user is verified, OnUnlock called.");
100 FormRequest currentFormRequest;
101 bool hasValidRequest = false;
102 for (auto& formRequest : formRequests_) {
103 if (currentCompId_ == formRequest.compId) {
104 currentFormRequest = formRequest;
105 formRequest.want.SetParam(FORM_RENDER_STATE, true);
106 hasValidRequest = true;
107 }
108 }
109
110 if (!hasValidRequest) {
111 HILOG_ERROR("Without valid form requests, current compId is %{public}s", currentCompId_.c_str());
112 return;
113 }
114 InnerAddForm(currentFormRequest);
115 }
116
SetVisibleChange(bool isVisible)117 void FormRendererGroup::SetVisibleChange(bool isVisible)
118 {
119 if (formRenderer_ == nullptr) {
120 HILOG_ERROR("SetVisibleChange failed, formRenderer is null");
121 return;
122 }
123 formRenderer_->SetVisibleChange(isVisible);
124 }
125
InnerAddForm(const FormRequest & formRequest)126 void FormRendererGroup::InnerAddForm(const FormRequest& formRequest)
127 {
128 HILOG_DEBUG("InnerAddForm called");
129 auto compId = formRequest.compId;
130 OHOS::AAFwk::Want want = formRequest.want;
131 AppExecFwk::FormJsInfo formJsInfo = formRequest.formJsInfo;
132 FormRenderEventReport::StartSurfaceNodeTimeoutReportTimer(formJsInfo.formId, formJsInfo.bundleName,
133 formJsInfo.formName);
134 if (formRenderer_ == nullptr || initState_ == FormRendererInitState::UNINITIALIZED) {
135 formRenderer_ = std::make_shared<FormRenderer>(context_, runtime_, eventHandler_);
136 if (!formRenderer_) {
137 HILOG_ERROR("InnerAddForm create form render failed");
138 return;
139 }
140 HILOG_INFO("InnerAddForm compId is %{public}s. formId is %{public}s, formJsInfo.formData.size is %{public}zu",
141 compId.c_str(),
142 std::to_string(formJsInfo.formId).c_str(),
143 formJsInfo.formData.size());
144 formRenderer_->AddForm(want, formJsInfo);
145 initState_ = FormRendererInitState::INITIALIZED;
146 } else if (initState_ == FormRendererInitState::PRE_INITIALIZED) {
147 HILOG_INFO("RunFormPage compId is %{public}s. formId is %{public}s, formJsInfo.formData.size is %{public}zu",
148 compId.c_str(),
149 std::to_string(formJsInfo.formId).c_str(),
150 formJsInfo.formData.size());
151 formRenderer_->RunFormPage(want, formJsInfo);
152 initState_ = FormRendererInitState::INITIALIZED;
153 } else { // initState_ == FormRendererInitState::INITIALIZED
154 HILOG_INFO("AttachForm compId is %{public}s, formRequests size is %{public}s, \
155 formJsInfo.formData.size is %{public}zu",
156 compId.c_str(),
157 std::to_string(formRequests_.size()).c_str(),
158 formJsInfo.formData.size());
159 formRenderer_->AttachForm(want, formJsInfo);
160 }
161 }
162
ReloadForm(const AppExecFwk::FormJsInfo & formJsInfo)163 void FormRendererGroup::ReloadForm(const AppExecFwk::FormJsInfo& formJsInfo)
164 {
165 if (formRenderer_ == nullptr) {
166 HILOG_ERROR("ReloadForm failed, formRenderer is null");
167 return;
168 }
169
170 formRenderer_->ReloadForm(formJsInfo.formSrc);
171 for (auto &formRequest : formRequests_) {
172 bool allDynamic = formJsInfo.isDynamic && formRequest.isDynamic;
173 if (!allDynamic && currentCompId_ == formRequest.compId) {
174 HILOG_INFO("SurfaceReuse due to change to static card when curCompId is %{public}s.",
175 formRequest.compId.c_str());
176 formRenderer_->OnSurfaceReuse(formJsInfo);
177 }
178 formRequest.formJsInfo = formJsInfo;
179 formRequest.isDynamic = formJsInfo.isDynamic;
180 }
181 }
182
UpdateFormSizeOfFormRequests(double width,double height,float borderWidth)183 void FormRendererGroup::UpdateFormSizeOfFormRequests(double width, double height, float borderWidth)
184 {
185 for (auto iter = formRequests_.begin(); iter != formRequests_.end(); ++iter) {
186 iter->want.SetParam(OHOS::AppExecFwk::Constants::PARAM_FORM_WIDTH_KEY, static_cast<double>(width));
187 iter->want.SetParam(OHOS::AppExecFwk::Constants::PARAM_FORM_HEIGHT_KEY, static_cast<double>(height));
188 iter->want.SetParam(OHOS::AppExecFwk::Constants::PARAM_FORM_BORDER_WIDTH_KEY, static_cast<float>(borderWidth));
189 }
190 if (formRenderer_ != nullptr) {
191 formRenderer_->UpdateFormSize(width, height, borderWidth);
192 } else {
193 HILOG_WARN("formRenderer is null");
194 }
195 }
196
UpdateForm(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)197 void FormRendererGroup::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
198 {
199 HILOG_INFO("UpdateForm formId %{public}s.", std::to_string(formJsInfo.formId).c_str());
200 if (formRenderer_ == nullptr) {
201 HILOG_ERROR("UpdateForm failed, formRenderer is null");
202 return;
203 }
204 formRenderer_->UpdateForm(formJsInfo);
205 }
206
DeleteForm(const std::string & compId)207 void FormRendererGroup::DeleteForm(const std::string& compId)
208 {
209 HILOG_INFO("DeleteForm compId is %{public}s, currentCompId is %{public}s, formRequests size is %{public}s.",
210 compId.c_str(), currentCompId_.c_str(), std::to_string(formRequests_.size()).c_str());
211
212 for (auto iter = formRequests_.begin(); iter != formRequests_.end(); ++iter) {
213 if (iter->compId == compId) {
214 formRequests_.erase(iter);
215 break;
216 }
217 }
218
219 if (compId != currentCompId_) {
220 return;
221 }
222
223 if (formRequests_.empty()) {
224 HILOG_INFO("Release renderer obj due to formRequests is empty.");
225 DeleteForm();
226 return;
227 }
228
229 FormRequest request = formRequests_.back();
230 currentCompId_ = request.compId;
231 HILOG_INFO("RestoreForm compId is %{public}s.", currentCompId_.c_str());
232 if (formRenderer_ == nullptr) {
233 HILOG_INFO("FormRenderer has destory");
234 return;
235 }
236 formRenderer_->AttachForm(request.want, request.formJsInfo);
237 }
238
IsFormRequestsEmpty()239 bool FormRendererGroup::IsFormRequestsEmpty()
240 {
241 return formRequests_.empty();
242 }
243
GetAllRendererFormRequests() const244 const std::vector<FormRequest>& FormRendererGroup::GetAllRendererFormRequests() const
245 {
246 return formRequests_;
247 }
248
GetOrderedAndCurrentCompIds() const249 std::pair<std::vector<std::string>, std::string> FormRendererGroup::GetOrderedAndCurrentCompIds() const
250 {
251 std::vector<std::string> orderedCompIds;
252 for (auto formRequest: formRequests_) {
253 orderedCompIds.emplace_back(formRequest.compId);
254 }
255 return std::make_pair(orderedCompIds, currentCompId_);
256 }
257
DeleteForm()258 void FormRendererGroup::DeleteForm()
259 {
260 if (formRenderer_ == nullptr) {
261 HILOG_INFO("FormRenderer has destory");
262 return;
263 }
264 formRenderer_->Destroy();
265 formRenderer_ = nullptr;
266 formRequests_.clear();
267 }
268
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)269 void FormRendererGroup::UpdateConfiguration(
270 const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
271 {
272 if (!config) {
273 HILOG_ERROR("UpdateConfiguration config is null");
274 return;
275 }
276 if (formRenderer_ == nullptr) {
277 HILOG_ERROR("UpdateConfiguration failed, formRenderer is null");
278 return;
279 }
280 formRenderer_->UpdateConfiguration(config);
281 }
282
RecycleForm(std::string & statusData) const283 void FormRendererGroup::RecycleForm(std::string& statusData) const
284 {
285 if (formRenderer_ == nullptr) {
286 HILOG_ERROR("RecycleForm failed, formRenderer is null");
287 return;
288 }
289 formRenderer_->RecycleForm(statusData);
290 }
291
RecoverRenderer(const std::vector<FormRequest> & formRequests,size_t currentCompIndex)292 void FormRendererGroup::RecoverRenderer(const std::vector<FormRequest>& formRequests, size_t currentCompIndex)
293 {
294 if (currentCompIndex >= formRequests.size()) {
295 HILOG_ERROR("current comp index %{public}zu invalid", currentCompIndex);
296 return;
297 }
298
299 const FormRequest ¤tComp = formRequests[currentCompIndex];
300 for (auto formRequest: formRequests) {
301 formRequests_.emplace_back(formRequest);
302 }
303 currentCompId_ = currentComp.compId;
304
305 bool isVerified = currentComp.want.GetBoolParam(FORM_RENDER_STATE, false);
306 if (isVerified) {
307 HILOG_DEBUG("user verified, start recover renderer");
308 InnerAddForm(currentComp);
309 return;
310 }
311 HILOG_INFO("user not verified, delay recover renderer");
312 PreInitAddForm(currentComp);
313 }
314
IsManagerDelegateValid(const OHOS::AAFwk::Want & want)315 bool FormRendererGroup::IsManagerDelegateValid(const OHOS::AAFwk::Want& want)
316 {
317 if (formRenderer_ == nullptr) {
318 return true;
319 }
320 return formRenderer_->IsManagerDelegateValid(want);
321 }
322 } // namespace Ace
323 } // namespace OHOS
324