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