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 "configuration.h"
19 #include "form_renderer.h"
20 #include "form_renderer_hilog.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 if (formRenderer_ == nullptr || initState_ == FormRendererInitState::UNINITIALIZED) {
133 formRenderer_ = std::make_shared<FormRenderer>(context_, runtime_, eventHandler_);
134 if (!formRenderer_) {
135 HILOG_ERROR("InnerAddForm create form render failed");
136 return;
137 }
138 HILOG_INFO("InnerAddForm compId is %{public}s. formId is %{public}s, formJsInfo.formData.size is %{public}zu",
139 compId.c_str(),
140 std::to_string(formJsInfo.formId).c_str(),
141 formJsInfo.formData.size());
142 formRenderer_->AddForm(want, formJsInfo);
143 initState_ = FormRendererInitState::INITIALIZED;
144 } else if (initState_ == FormRendererInitState::PRE_INITIALIZED) {
145 HILOG_INFO("RunFormPage compId is %{public}s. formId is %{public}s, formJsInfo.formData.size is %{public}zu",
146 compId.c_str(),
147 std::to_string(formJsInfo.formId).c_str(),
148 formJsInfo.formData.size());
149 formRenderer_->RunFormPage(want, formJsInfo);
150 initState_ = FormRendererInitState::INITIALIZED;
151 } else { // initState_ == FormRendererInitState::INITIALIZED
152 HILOG_INFO("AttachForm compId is %{public}s, formRequests size is %{public}s, \
153 formJsInfo.formData.size is %{public}zu",
154 compId.c_str(),
155 std::to_string(formRequests_.size()).c_str(),
156 formJsInfo.formData.size());
157 formRenderer_->AttachForm(want, formJsInfo);
158 }
159 }
160
ReloadForm(const AppExecFwk::FormJsInfo & formJsInfo)161 void FormRendererGroup::ReloadForm(const AppExecFwk::FormJsInfo& formJsInfo)
162 {
163 if (formRenderer_ == nullptr) {
164 HILOG_ERROR("ReloadForm failed, formRenderer is null");
165 return;
166 }
167
168 formRenderer_->ReloadForm(formJsInfo.formSrc);
169 for (auto &formRequest : formRequests_) {
170 bool allDynamic = formJsInfo.isDynamic && formRequest.isDynamic;
171 if (!allDynamic && currentCompId_ == formRequest.compId) {
172 HILOG_INFO("SurfaceReuse due to change to static card when curCompId is %{public}s.",
173 formRequest.compId.c_str());
174 formRenderer_->OnSurfaceReuse(formJsInfo);
175 }
176 formRequest.formJsInfo = formJsInfo;
177 formRequest.isDynamic = formJsInfo.isDynamic;
178 }
179 }
180
UpdateForm(const OHOS::AppExecFwk::FormJsInfo & formJsInfo)181 void FormRendererGroup::UpdateForm(const OHOS::AppExecFwk::FormJsInfo& formJsInfo)
182 {
183 HILOG_INFO("UpdateForm formId %{public}s.", std::to_string(formJsInfo.formId).c_str());
184 if (formRenderer_ == nullptr) {
185 HILOG_ERROR("UpdateForm failed, formRenderer is null");
186 return;
187 }
188 formRenderer_->UpdateForm(formJsInfo);
189 }
190
DeleteForm(const std::string & compId)191 void FormRendererGroup::DeleteForm(const std::string& compId)
192 {
193 HILOG_INFO("DeleteForm compId is %{public}s, currentCompId is %{public}s, formRequests size is %{public}s.",
194 compId.c_str(), currentCompId_.c_str(), std::to_string(formRequests_.size()).c_str());
195
196 for (auto iter = formRequests_.begin(); iter != formRequests_.end(); ++iter) {
197 if (iter->compId == compId) {
198 formRequests_.erase(iter);
199 break;
200 }
201 }
202
203 if (compId != currentCompId_) {
204 return;
205 }
206
207 if (formRequests_.empty()) {
208 HILOG_INFO("Release renderer obj due to formRequests is empty.");
209 DeleteForm();
210 return;
211 }
212
213 FormRequest request = formRequests_.back();
214 currentCompId_ = request.compId;
215 HILOG_INFO("RestoreForm compId is %{public}s.", currentCompId_.c_str());
216 if (formRenderer_ == nullptr) {
217 HILOG_INFO("FormRenderer has destory");
218 return;
219 }
220 formRenderer_->AttachForm(request.want, request.formJsInfo);
221 }
222
IsFormRequestsEmpty()223 bool FormRendererGroup::IsFormRequestsEmpty()
224 {
225 return formRequests_.empty();
226 }
227
GetAllRendererFormRequests() const228 const std::vector<FormRequest>& FormRendererGroup::GetAllRendererFormRequests() const
229 {
230 return formRequests_;
231 }
232
GetOrderedAndCurrentCompIds() const233 std::pair<std::vector<std::string>, std::string> FormRendererGroup::GetOrderedAndCurrentCompIds() const
234 {
235 std::vector<std::string> orderedCompIds;
236 for (auto formRequest: formRequests_) {
237 orderedCompIds.emplace_back(formRequest.compId);
238 }
239 return std::make_pair(orderedCompIds, currentCompId_);
240 }
241
DeleteForm()242 void FormRendererGroup::DeleteForm()
243 {
244 if (formRenderer_ == nullptr) {
245 HILOG_INFO("FormRenderer has destory");
246 return;
247 }
248 formRenderer_->Destroy();
249 formRenderer_ = nullptr;
250 formRequests_.clear();
251 }
252
UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)253 void FormRendererGroup::UpdateConfiguration(
254 const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
255 {
256 if (!config) {
257 HILOG_ERROR("UpdateConfiguration config is null");
258 return;
259 }
260 if (formRenderer_ == nullptr) {
261 HILOG_ERROR("UpdateConfiguration failed, formRenderer is null");
262 return;
263 }
264 formRenderer_->UpdateConfiguration(config);
265 }
266
RecycleForm(std::string & statusData) const267 void FormRendererGroup::RecycleForm(std::string& statusData) const
268 {
269 if (formRenderer_ == nullptr) {
270 HILOG_ERROR("RecycleForm failed, formRenderer is null");
271 return;
272 }
273 formRenderer_->RecycleForm(statusData);
274 }
275
RecoverRenderer(const std::vector<FormRequest> & formRequests,size_t currentCompIndex)276 void FormRendererGroup::RecoverRenderer(const std::vector<FormRequest>& formRequests, size_t currentCompIndex)
277 {
278 if (currentCompIndex >= formRequests.size()) {
279 HILOG_ERROR("current comp index %{public}zu invalid", currentCompIndex);
280 return;
281 }
282
283 const FormRequest ¤tComp = formRequests[currentCompIndex];
284 for (auto formRequest: formRequests) {
285 formRequests_.emplace_back(formRequest);
286 }
287 currentCompId_ = currentComp.compId;
288
289 bool isVerified = currentComp.want.GetBoolParam(FORM_RENDER_STATE, false);
290 if (isVerified) {
291 HILOG_DEBUG("user verified, start recover renderer");
292 InnerAddForm(currentComp);
293 return;
294 }
295 HILOG_INFO("user not verified, delay recover renderer");
296 PreInitAddForm(currentComp);
297 }
298 } // namespace Ace
299 } // namespace OHOS
300