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