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_render_mgr.h"
17
18 #include <mutex>
19
20 #include "fms_log_wrapper.h"
21 #include "form_ams_helper.h"
22 #include "form_bms_helper.h"
23 #include "form_cache_mgr.h"
24 #include "form_constants.h"
25 #include "form_data_mgr.h"
26 #include "form_event_report.h"
27 #include "form_host_interface.h"
28 #include "form_mgr_errors.h"
29 #include "form_supply_callback.h"
30 #include "form_task_mgr.h"
31 #include "form_trust_mgr.h"
32 #include "form_util.h"
33 #include "ipc_skeleton.h"
34 #include "os_account_manager.h"
35 #include "want.h"
36
37 namespace OHOS {
38 namespace AppExecFwk {
39 namespace {
40 constexpr size_t LAST_CONNECTION = 1;
41 }
42 using Want = OHOS::AAFwk::Want;
FormRenderMgr()43 FormRenderMgr::FormRenderMgr()
44 {
45 }
~FormRenderMgr()46 FormRenderMgr::~FormRenderMgr()
47 {
48 }
49
GetFormRenderState() const50 void FormRenderMgr::GetFormRenderState() const
51 {
52 HILOG_INFO("RenderForm for the first time");
53 // Check whether the account is authenticated.
54 bool isVerified = false;
55 AccountSA::OsAccountManager::IsOsAccountVerified(FormUtil::GetCurrentAccountId(), isVerified);
56 HILOG_INFO("isVerified: %{public}d", isVerified);
57 std::lock_guard<std::mutex> lock(isVerifiedMutex_);
58 isVerified_ = isVerified;
59 }
60
GetIsVerified() const61 bool FormRenderMgr::GetIsVerified() const
62 {
63 HILOG_DEBUG("GetIsVerified.");
64 std::lock_guard<std::mutex> lock(isVerifiedMutex_);
65 return isVerified_;
66 }
67
RenderForm(const FormRecord & formRecord,const WantParams & wantParams,const sptr<IRemoteObject> & hostToken)68 ErrCode FormRenderMgr::RenderForm(
69 const FormRecord &formRecord, const WantParams &wantParams, const sptr<IRemoteObject> &hostToken)
70 {
71 HILOG_INFO("RenderForm formId: %{public}" PRId64 "", formRecord.formId);
72 std::once_flag flag;
73 std::function<void()> func = std::bind(&FormRenderMgr::GetFormRenderState, this);
74 std::call_once(flag, func);
75 HILOG_INFO("The authentication status of the current user is : %{public}d", isVerified_);
76 if (formRecord.uiSyntax != FormType::ETS) {
77 return ERR_OK;
78 }
79 if (formRecord.formId <= 0) {
80 HILOG_ERROR("%{public}s fail, formId should be greater than 0.", __func__);
81 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
82 }
83
84 int32_t userId = FormUtil::GetCurrentAccountId();
85 Want want;
86 want.SetParams(wantParams);
87 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + formRecord.bundleName);
88 {
89 std::lock_guard<std::mutex> lock(isVerifiedMutex_);
90 want.SetParam(Constants::FORM_RENDER_STATE, isVerified_);
91 }
92 if (atomicRerenderCount_ > 0) {
93 --atomicRerenderCount_;
94 } else {
95 atomicRerenderCount_ = 0;
96 }
97 if (hostToken) {
98 HILOG_DEBUG("Add host token");
99 AddHostToken(hostToken, formRecord.formId);
100 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
101 }
102
103 bool connectionExisted = false;
104 sptr<FormRenderConnection> connection = nullptr;
105 {
106 std::lock_guard<std::mutex> lock(resourceMutex_);
107 HILOG_DEBUG("renderFormConnections_ size: %{public}zu.", renderFormConnections_.size());
108 auto conIterator = renderFormConnections_.find(formRecord.formId);
109 if (conIterator != renderFormConnections_.end()) {
110 connectionExisted = true;
111 connection = conIterator->second;
112 }
113 }
114 if (connectionExisted) {
115 if (connection == nullptr) {
116 HILOG_ERROR("connection is null.");
117 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
118 }
119 if (renderRemoteObj_ == nullptr) {
120 connection->UpdateWantParams(want.GetParams());
121 ErrCode ret = ConnectRenderService(connection);
122 HILOG_INFO("renderRemoteObj is nullptr, render may exit, need reconnect, ret: %{public}d.", ret);
123 if (ret) {
124 HandleConnectFailed(formRecord.formId, ret);
125 }
126 return ret;
127 }
128 auto remoteObject = renderRemoteObj_->AsObject();
129 if (remoteObject == nullptr) {
130 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
131 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
132 }
133 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
134 FormTaskMgr::GetInstance().PostRenderForm(formRecord, want, remoteObject);
135 return ERR_OK;
136 }
137
138 auto formRenderConnection = new (std::nothrow) FormRenderConnection(formRecord, want.GetParams());
139 if (formRenderConnection == nullptr) {
140 HILOG_ERROR("formRenderConnection is null.");
141 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
142 }
143 ErrCode errorCode = ConnectRenderService(formRenderConnection);
144 if (errorCode != ERR_OK) {
145 HILOG_ERROR("%{public}s fail, ConnectServiceAbility failed.", __func__);
146 HandleConnectFailed(formRecord.formId, errorCode);
147 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
148 }
149 return ERR_OK;
150 }
151
UpdateRenderingForm(int64_t formId,const FormProviderData & formProviderData,const WantParams & wantParams,bool mergeData)152 ErrCode FormRenderMgr::UpdateRenderingForm(int64_t formId, const FormProviderData &formProviderData,
153 const WantParams &wantParams, bool mergeData)
154 {
155 HILOG_DEBUG("RenderForm with formId.");
156 FormRecord formRecord;
157 bool isGetFormRecord = FormDataMgr::GetInstance().GetFormRecord(formId, formRecord);
158 if (!isGetFormRecord) {
159 HILOG_ERROR("%{public}s fail, not exist such form, formId:%{public}" PRId64 "", __func__, formId);
160 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
161 }
162 if (mergeData) {
163 nlohmann::json jsonData = formProviderData.GetData();
164 formRecord.formProviderInfo.MergeData(jsonData);
165 auto providerData = formRecord.formProviderInfo.GetFormData();
166 providerData.SetImageDataState(formProviderData.GetImageDataState());
167 providerData.SetImageDataMap(formProviderData.GetImageDataMap());
168 formRecord.formProviderInfo.SetFormData(providerData);
169 } else {
170 formRecord.formProviderInfo.SetFormData(formProviderData);
171 }
172
173 if (formRecord.formProviderInfo.NeedCache()) {
174 FormCacheMgr::GetInstance().AddData(formId, formRecord.formProviderInfo.GetFormData());
175 } else {
176 HILOG_DEBUG("need to delete data.");
177 FormCacheMgr::GetInstance().DeleteData(formId);
178 }
179 FormDataMgr::GetInstance().SetFormCacheInited(formId, true);
180
181 Want want;
182 want.SetParams(wantParams);
183 want.SetParam(Constants::FORM_RENDER_TYPE_KEY, Constants::UPDATE_RENDERING_FORM);
184 int32_t userId = FormUtil::GetCurrentAccountId();
185 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + formRecord.bundleName);
186 {
187 std::lock_guard<std::mutex> lock(resourceMutex_);
188 auto conIterator = renderFormConnections_.find(formRecord.formId);
189 if (conIterator != renderFormConnections_.end()) {
190 auto connection = conIterator->second;
191 if (connection == nullptr) {
192 HILOG_ERROR("connection is null.");
193 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
194 }
195 if (renderRemoteObj_ == nullptr) {
196 HILOG_ERROR("%{public}s, renderRemoteObj_ is nullptr", __func__);
197 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
198 }
199 auto remoteObject = renderRemoteObj_->AsObject();
200 if (remoteObject == nullptr) {
201 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
202 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
203 }
204 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
205 FormTaskMgr::GetInstance().PostRenderForm(formRecord, std::move(want), remoteObject);
206 return ERR_OK;
207 }
208 }
209 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
210 }
211
ReloadForm(const std::vector<FormRecord> && formRecords,const std::string & bundleName,int32_t userId)212 ErrCode FormRenderMgr::ReloadForm(
213 const std::vector<FormRecord> &&formRecords, const std::string &bundleName, int32_t userId)
214 {
215 if (renderRemoteObj_ == nullptr) {
216 HILOG_ERROR("%{public}s, renderRemoteObj_ is nullptr", __func__);
217 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
218 }
219 auto remoteObject = renderRemoteObj_->AsObject();
220 if (remoteObject == nullptr) {
221 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
222 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
223 }
224 Want want;
225 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + bundleName);
226 FormTaskMgr::GetInstance().PostReloadForm(std::forward<decltype(formRecords)>(formRecords), want, remoteObject);
227 return ERR_OK;
228 }
229
SetFormRenderState(bool isVerified)230 void FormRenderMgr::SetFormRenderState(bool isVerified)
231 {
232 HILOG_DEBUG("start to set form render state.");
233 std::lock_guard<std::mutex> lock(isVerifiedMutex_);
234 isVerified_ = isVerified;
235 }
236
PostOnUnlockTask()237 void FormRenderMgr::PostOnUnlockTask()
238 {
239 HILOG_DEBUG("called");
240 if (renderRemoteObj_ == nullptr) {
241 HILOG_ERROR("renderRemoteObj_ is nullptr");
242 return;
243 }
244 auto remoteObject = renderRemoteObj_->AsObject();
245 if (remoteObject == nullptr) {
246 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
247 return;
248 }
249 FormTaskMgr::GetInstance().PostOnUnlock(remoteObject);
250 }
251
AddAcquireProviderFormInfoTask(std::function<void ()> task)252 void FormRenderMgr::AddAcquireProviderFormInfoTask(std::function<void()> task)
253 {
254 HILOG_DEBUG("called");
255 std::lock_guard<std::mutex> lock(taskQueueMutex_);
256 taskQueue_.push(task);
257 }
258
ExecAcquireProviderTask()259 void FormRenderMgr::ExecAcquireProviderTask()
260 {
261 HILOG_INFO("start to execute asynchronous tasks in the queue.");
262 std::lock_guard<std::mutex> lock(taskQueueMutex_);
263 while (!taskQueue_.empty()) {
264 auto task = taskQueue_.front();
265 task();
266 taskQueue_.pop();
267 }
268 }
269
OnUnlock()270 void FormRenderMgr::OnUnlock()
271 {
272 HILOG_DEBUG("called. The authentication status of the current user is true.");
273 SetFormRenderState(true);
274 PostOnUnlockTask();
275 ExecAcquireProviderTask();
276 }
277
StopRenderingForm(int64_t formId,const FormRecord & formRecord,const std::string & compId,const sptr<IRemoteObject> & hostToken)278 ErrCode FormRenderMgr::StopRenderingForm(int64_t formId, const FormRecord &formRecord, const std::string &compId, const sptr<IRemoteObject> &hostToken)
279 {
280 HILOG_DEBUG("%{public}s called.", __func__);
281 if (formRecord.uiSyntax != FormType::ETS) {
282 return ERR_OK;
283 }
284 if (formRecord.abilityName.empty()) {
285 HILOG_ERROR("%{public}s, formRecord.abilityName is empty.", __func__);
286 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
287 }
288 if (formRecord.bundleName.empty()) {
289 HILOG_ERROR("%{public}s, formRecord.bundleName is empty.", __func__);
290 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
291 }
292 Want want;
293 int32_t userId = FormUtil::GetCurrentAccountId();
294 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + formRecord.bundleName);
295 if (!compId.empty()) {
296 want.SetParam(Constants::FORM_RENDER_COMP_ID, compId);
297 }
298 if (hostToken) {
299 HILOG_DEBUG("StopRenderingForm Add host token");
300 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
301 }
302
303 {
304 std::lock_guard<std::mutex> lock(resourceMutex_);
305 auto conIterator = renderFormConnections_.find(formRecord.formId);
306 if (conIterator != renderFormConnections_.end()) {
307 auto connection = conIterator->second;
308 if (connection == nullptr) {
309 HILOG_ERROR("connection is null.");
310 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
311 }
312 if (renderRemoteObj_ == nullptr) {
313 HILOG_ERROR("%{public}s, renderRemoteObj_ is nullptr", __func__);
314 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
315 }
316 auto remoteObject = renderRemoteObj_->AsObject();
317 if (remoteObject == nullptr) {
318 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
319 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
320 }
321 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
322 FormTaskMgr::GetInstance().PostStopRenderingForm(formRecord, std::move(want), remoteObject);
323 return ERR_OK;
324 }
325 }
326 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
327 }
328
RenderFormCallback(int64_t formId,const Want & want)329 ErrCode FormRenderMgr::RenderFormCallback(int64_t formId, const Want &want)
330 {
331 HILOG_INFO("%{public}s called.", __func__);
332 return ERR_OK;
333 }
334
StopRenderingFormCallback(int64_t formId,const Want & want)335 ErrCode FormRenderMgr::StopRenderingFormCallback(int64_t formId, const Want &want)
336 {
337 HILOG_INFO("%{public}s called.", __func__);
338 int32_t renderFormConnectionSize = 0;
339 sptr<FormRenderConnection> stopConnection = nullptr;
340 {
341 std::lock_guard<std::mutex> lock(resourceMutex_);
342 HILOG_DEBUG("renderFormConnections_ size: %{public}zu.", renderFormConnections_.size());
343 auto conIterator = renderFormConnections_.find(formId);
344 if (conIterator == renderFormConnections_.end()) {
345 HILOG_ERROR("Can not find formId in map.");
346 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
347 }
348 stopConnection = conIterator->second;
349 renderFormConnectionSize = renderFormConnections_.size();
350 for (auto iter = etsHosts_.begin(); iter != etsHosts_.end();) {
351 iter->second.erase(formId);
352 if (iter->second.empty()) {
353 HILOG_INFO("All forms of the host have been removed, remove the host.");
354 iter = etsHosts_.erase(iter);
355 } else {
356 ++iter;
357 }
358 }
359 renderFormConnections_.erase(formId);
360 }
361 if (stopConnection == nullptr) {
362 HILOG_ERROR("Can not find stopConnection in map.");
363 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
364 }
365 DisconnectRenderService(stopConnection, renderFormConnectionSize);
366 return ERR_OK;
367 }
368
ReleaseRenderer(int64_t formId,const FormRecord & formRecord,const std::string & compId)369 ErrCode FormRenderMgr::ReleaseRenderer(int64_t formId, const FormRecord &formRecord, const std::string &compId)
370 {
371 HILOG_DEBUG("%{public}s called.", __func__);
372 if (formRecord.uiSyntax != FormType::ETS) {
373 return ERR_OK;
374 }
375 if (formRecord.abilityName.empty()) {
376 HILOG_ERROR("%{public}s, formRecord.abilityName is empty.", __func__);
377 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
378 }
379 if (formRecord.bundleName.empty()) {
380 HILOG_ERROR("%{public}s, formRecord.bundleName is empty.", __func__);
381 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
382 }
383
384 int32_t userId = FormUtil::GetCurrentAccountId();
385 std::string uid = std::to_string(userId) + formRecord.bundleName;
386 {
387 std::lock_guard<std::mutex> lock(resourceMutex_);
388 auto conIterator = renderFormConnections_.find(formRecord.formId);
389 if (conIterator != renderFormConnections_.end()) {
390 auto connection = conIterator->second;
391 if (connection == nullptr) {
392 HILOG_ERROR("connection is null.");
393 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
394 }
395 if (renderRemoteObj_ == nullptr) {
396 HILOG_ERROR("%{public}s, renderRemoteObj_ is nullptr", __func__);
397 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
398 }
399 auto remoteObject = renderRemoteObj_->AsObject();
400 if (remoteObject == nullptr) {
401 HILOG_ERROR("remoteObject is nullptr, can not get obj from renderRemoteObj.");
402 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
403 }
404 FormTaskMgr::GetInstance().PostReleaseRenderer(formId, compId, uid, remoteObject);
405 return ERR_OK;
406 }
407 }
408 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
409 }
410
AddConnection(int64_t formId,sptr<FormRenderConnection> connection)411 ErrCode FormRenderMgr::AddConnection(int64_t formId, sptr<FormRenderConnection> connection)
412 {
413 HILOG_INFO("%{public}s called.", __func__);
414 if (connection == nullptr) {
415 HILOG_ERROR("Input FormRenderConnection is nullptr.");
416 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
417 }
418 size_t renderFormConnectionSize = 0;
419 sptr<FormRenderConnection> oldConnection = nullptr;
420 {
421 std::lock_guard<std::mutex> lock(resourceMutex_);
422 int32_t connectKey = static_cast<int32_t>(FormUtil::GetCurrentMillisecond());
423 auto conIterator = renderFormConnections_.find(formId);
424 if (conIterator == renderFormConnections_.end()) {
425 connection->SetConnectId(connectKey);
426 renderFormConnections_.emplace(formId, connection);
427 } else if (renderFormConnections_[formId]->GetConnectId() != connection->GetConnectId()) {
428 HILOG_WARN("Duplicate connection of formId: %{public}" PRId64 ", delete old connection", formId);
429 renderFormConnectionSize = renderFormConnections_.size();
430 oldConnection = renderFormConnections_[formId];
431 renderFormConnections_[formId] = connection;
432 connection->SetConnectId(connectKey);
433 }
434 HILOG_DEBUG("renderFormConnections size: %{public}zu.", renderFormConnections_.size());
435 }
436 if (oldConnection) {
437 DisconnectRenderService(oldConnection, renderFormConnectionSize);
438 }
439 return ERR_OK;
440 }
441
RemoveConnection(int64_t formId)442 void FormRenderMgr::RemoveConnection(int64_t formId)
443 {
444 HILOG_INFO("Call.");
445 std::lock_guard<std::mutex> lock(resourceMutex_);
446 if (renderFormConnections_.find(formId) != renderFormConnections_.end()) {
447 HILOG_DEBUG("Remove connection of formId: %{public}" PRId64 "", formId);
448 renderFormConnections_.erase(formId);
449 }
450 }
451
RerenderAllForms()452 void FormRenderMgr::RerenderAllForms()
453 {
454 HILOG_INFO("Render is dead.");
455 renderRemoteObj_ = nullptr;
456
457 {
458 std::lock_guard<std::mutex> lock(resourceMutex_);
459 atomicRerenderCount_ = renderFormConnections_.size();
460 if (etsHosts_.empty() || renderFormConnections_.empty()) {
461 HILOG_INFO("All hosts died or all connections erased, no need to rerender.");
462 return;
463 }
464 HILOG_INFO("The forms need to rerender count: %{public}zu.", renderFormConnections_.size());
465 for (auto &item : renderFormConnections_) {
466 if (item.second == nullptr) {
467 HILOG_ERROR("Connection is nullptr.");
468 continue;
469 }
470 item.second->SetStateDisconnected();
471 }
472 }
473
474 NotifyHostRenderServiceIsDead();
475 }
476
CleanFormHost(const sptr<IRemoteObject> & host)477 void FormRenderMgr::CleanFormHost(const sptr<IRemoteObject> &host)
478 {
479 HILOG_INFO("Host is died or been removed, notify FormRenderService and remove host.");
480 RemoveHostToken(host);
481 if (renderRemoteObj_ == nullptr) {
482 HILOG_WARN("renderRemoteObj is nullptr, render service may exit already.");
483 return;
484 }
485 renderRemoteObj_->CleanFormHost(host);
486 }
487
AddRenderDeathRecipient(const sptr<IRemoteObject> & remoteObject)488 void FormRenderMgr::AddRenderDeathRecipient(const sptr<IRemoteObject> &remoteObject)
489 {
490 if (renderRemoteObj_) {
491 HILOG_INFO("renderDeathRecipient is exist, no need to add again.");
492 return;
493 }
494
495 HILOG_INFO("Get renderRemoteObj, add death recipient.");
496 auto renderRemoteObj = iface_cast<IFormRender>(remoteObject);
497 if (renderRemoteObj == nullptr) {
498 HILOG_ERROR("renderRemoteObj is nullptr.");
499 return;
500 }
501
502 if (renderDeathRecipient_ == nullptr) {
503 renderDeathRecipient_ = new FormRenderRecipient([]() {
504 FormRenderMgr::GetInstance().RerenderAllForms();
505 });
506 }
507 if (!remoteObject->AddDeathRecipient(renderDeathRecipient_)) {
508 HILOG_ERROR("AddDeathRecipient failed.");
509 return;
510 }
511 renderRemoteObj_ = renderRemoteObj;
512 }
513
ConnectRenderService(const sptr<FormRenderConnection> & connection) const514 inline ErrCode FormRenderMgr::ConnectRenderService(const sptr<FormRenderConnection> &connection) const
515 {
516 if (connection == nullptr) {
517 HILOG_INFO("connection is nullptr.");
518 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
519 }
520 Want want;
521 want.SetElementName("com.ohos.formrenderservice", "ServiceExtension");
522 want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
523 connection->SetStateConnecting();
524 return FormAmsHelper::GetInstance().ConnectServiceAbility(want, connection);
525 }
526
DisconnectRenderService(const sptr<FormRenderConnection> connection,size_t size) const527 void FormRenderMgr::DisconnectRenderService(const sptr<FormRenderConnection> connection, size_t size) const
528 {
529 if (size == LAST_CONNECTION) {
530 HILOG_INFO("This is the last connection, disconnect render service delay");
531 FormAmsHelper::GetInstance().DisconnectServiceAbilityDelay(connection);
532 } else {
533 HILOG_DEBUG("Disconnect render service ability");
534 FormAmsHelper::GetInstance().DisconnectServiceAbility(connection);
535 }
536 }
537
OnRenderingBlock(const std::string & bundleName)538 void FormRenderMgr::OnRenderingBlock(const std::string &bundleName)
539 {
540 HILOG_INFO("OnRenderingBlock called, bundleName: %{public}s.", bundleName.c_str());
541 FormEventInfo eventInfo;
542 eventInfo.bundleName = bundleName;
543 FormEventReport::SendFormEvent(
544 FormEventName::FORM_RENDER_BLOCK, HiSysEventType::FAULT, eventInfo);
545
546 FormTrustMgr::GetInstance().MarkTrustFlag(bundleName, false);
547
548 Want want;
549 want.SetElementName("com.ohos.formrenderservice", "ServiceExtension");
550 want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
551 FormAmsHelper::GetInstance().StopExtensionAbility(want);
552 }
553
IsNeedRender(int64_t formId)554 bool FormRenderMgr::IsNeedRender(int64_t formId)
555 {
556 FormRecord formRecord;
557 bool isGetFormRecord = FormDataMgr::GetInstance().GetFormRecord(formId, formRecord);
558 if (!isGetFormRecord) {
559 HILOG_ERROR("%{public}s fail, not exist such form, formId:%{public}" PRId64 "", __func__, formId);
560 return false;
561 }
562 if (formRecord.uiSyntax != FormType::ETS) {
563 HILOG_DEBUG("%{public}s fail, no need render, formId:%{public}" PRId64 "", __func__, formId);
564 return false;
565 }
566 return true;
567 }
568
AddHostToken(const sptr<IRemoteObject> & host,int64_t formId)569 inline void FormRenderMgr::AddHostToken(const sptr<IRemoteObject> &host, int64_t formId)
570 {
571 std::lock_guard<std::mutex> lock(resourceMutex_);
572 auto iter = etsHosts_.find(host);
573 if (iter == etsHosts_.end()) {
574 HILOG_DEBUG("Add host, current etsHosts.size: %{public}zu.", etsHosts_.size());
575 std::unordered_set<int64_t> formIdSet;
576 formIdSet.emplace(formId);
577 etsHosts_.emplace(host, formIdSet);
578 } else {
579 HILOG_DEBUG("Add formId to host, current etsHosts.size: %{public}zu.", etsHosts_.size());
580 iter->second.emplace(formId);
581 }
582 }
583
RemoveHostToken(const sptr<IRemoteObject> & host)584 void FormRenderMgr::RemoveHostToken(const sptr<IRemoteObject> &host)
585 {
586 int32_t left = 0;
587 std::unordered_map<int64_t, sptr<FormRenderConnection>> connections;
588 {
589 std::lock_guard<std::mutex> lock(resourceMutex_);
590 auto iter = etsHosts_.find(host);
591 if (iter == etsHosts_.end()) {
592 HILOG_ERROR("Can not find host in etsHosts.");
593 return;
594 }
595 auto formIdSet = iter->second;
596 etsHosts_.erase(host);
597 if (etsHosts_.empty()) {
598 HILOG_DEBUG("etsHosts is empty, disconnect all connections size: %{public}zu.",
599 renderFormConnections_.size());
600 connections.swap(renderFormConnections_);
601 } else {
602 for (const int64_t formId : formIdSet) {
603 FormRecord formRecord;
604 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
605 connections.emplace(formId, renderFormConnections_[formId]);
606 renderFormConnections_.erase(formId);
607 }
608 }
609 }
610 left = renderFormConnections_.size();
611 }
612 for (auto iter = connections.begin(); iter != connections.end();) {
613 DisconnectRenderService(iter->second, connections.size() > left ? connections.size() : left);
614 iter = connections.erase(iter);
615 }
616 }
617
NotifyHostRenderServiceIsDead() const618 void FormRenderMgr::NotifyHostRenderServiceIsDead() const
619 {
620 std::unordered_map<sptr<IRemoteObject>, std::unordered_set<int64_t>, RemoteObjHash> hostsForNotify;
621 {
622 std::lock_guard<std::mutex> lock(resourceMutex_);
623 HILOG_INFO("Notify hosts the render is dead, hosts.size: %{public}zu.", etsHosts_.size());
624 auto tmpMap(etsHosts_);
625 hostsForNotify.swap(tmpMap);
626 }
627 for (const auto &item : hostsForNotify) {
628 auto hostClient = iface_cast<IFormHost>(item.first);
629 if (hostClient == nullptr) {
630 HILOG_ERROR("hostClient is nullptr");
631 continue;
632 }
633 hostClient->OnError(ERR_APPEXECFWK_FORM_RENDER_SERVICE_DIED, "FormRenderService is dead.");
634 }
635 }
636
HandleConnectFailed(int64_t formId,int32_t errorCode) const637 void FormRenderMgr::HandleConnectFailed(int64_t formId, int32_t errorCode) const
638 {
639 HILOG_ERROR("Connect render service failed, formId: %{public}" PRId64 ", errorCode: %{public}d",
640 formId, errorCode);
641 std::vector<sptr<IRemoteObject>> formHostObjs;
642 FormDataMgr::GetInstance().GetFormHostRemoteObj(formId, formHostObjs);
643 for (const auto &host : formHostObjs) {
644 auto hostClient = iface_cast<IFormHost>(host);
645 if (hostClient == nullptr) {
646 HILOG_ERROR("hostClient is nullptr");
647 continue;
648 }
649 hostClient->OnError(errorCode, "Connect FormRenderService failed");
650 }
651 }
652
IsRerenderForRenderServiceDied(int64_t formId)653 bool FormRenderMgr::IsRerenderForRenderServiceDied(int64_t formId)
654 {
655 bool ret = IsNeedRender(formId) && (atomicRerenderCount_ > 0);
656 HILOG_DEBUG("Is need to rerender: %{public}d.", ret);
657 return ret;
658 }
659
OnRemoteDied(const wptr<IRemoteObject> & remote)660 void FormRenderRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
661 {
662 HILOG_ERROR("Recv FormRenderService death notice");
663
664 if (handler_) {
665 handler_();
666 }
667 }
668
FormRenderRecipient(RemoteDiedHandler handler)669 FormRenderRecipient::FormRenderRecipient(RemoteDiedHandler handler) : handler_(handler) {}
670
~FormRenderRecipient()671 FormRenderRecipient::~FormRenderRecipient() {}
672 } // namespace AppExecFwk
673 } // namespace OHOS
674