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