• 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_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