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_supply_callback.h"
31 #include "form_task_mgr.h"
32 #include "form_trust_mgr.h"
33 #include "form_util.h"
34 #include "ipc_skeleton.h"
35 #include "os_account_manager.h"
36 #include "want.h"
37 #include "form_info_rdb_storage_mgr.h"
38 #include "form_status_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 const int FORM_DISCONNECT_FRS_DELAY_TIME = 5000; // ms
46 }
47 using Want = OHOS::AAFwk::Want;
FormRenderMgrInner()48 FormRenderMgrInner::FormRenderMgrInner()
49 {
50 }
~FormRenderMgrInner()51 FormRenderMgrInner::~FormRenderMgrInner()
52 {
53 }
54
RenderForm(const FormRecord & formRecord,Want & want,const sptr<IRemoteObject> & hostToken)55 ErrCode FormRenderMgrInner::RenderForm(
56 const FormRecord &formRecord, Want &want, const sptr<IRemoteObject> &hostToken)
57 {
58 if (atomicRerenderCount_ > 0) {
59 --atomicRerenderCount_;
60 } else {
61 atomicRerenderCount_ = 0;
62 }
63 if (hostToken) {
64 HILOG_DEBUG("Add host token");
65 AddHostToken(hostToken, formRecord.formId);
66 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
67 }
68 if (!isActiveUser_) {
69 HILOG_WARN("isActiveUser is false, return");
70 return ERR_APPEXECFWK_FORM_RENDER_SERVICE_DIED;
71 }
72 FillBundleInfo(want, formRecord.bundleName);
73
74 bool connectionExisted = false;
75 sptr<FormRenderConnection> connection = nullptr;
76 {
77 std::lock_guard<std::mutex> lock(resourceMutex_);
78 HILOG_DEBUG("renderFormConnections_ size:%{public}zu", renderFormConnections_.size());
79 auto conIterator = renderFormConnections_.find(formRecord.formId);
80 if (conIterator != renderFormConnections_.end()) {
81 connectionExisted = true;
82 connection = conIterator->second;
83 }
84 }
85 if (connectionExisted) {
86 if (connection == nullptr) {
87 HILOG_ERROR("null connection");
88 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
89 }
90 std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
91 if (renderRemoteObj_ == nullptr) {
92 connection->UpdateFormRecord(formRecord);
93 connection->UpdateWantParams(want.GetParams());
94 ErrCode ret = ConnectRenderService(connection, formRecord.privacyLevel);
95 HILOG_INFO("ret:%{public}d", ret);
96 if (ret) {
97 FormRenderMgr::GetInstance().HandleConnectFailed(formRecord.formId, ret);
98 }
99 return ret;
100 }
101 auto remoteObject = renderRemoteObj_->AsObject();
102 if (remoteObject == nullptr) {
103 HILOG_ERROR("null remoteObject");
104 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
105 }
106 guard.unlock();
107 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
108 FormTaskMgr::GetInstance().PostRenderForm(formRecord, want, remoteObject);
109 return ERR_OK;
110 }
111
112 auto formRenderConnection = new (std::nothrow) FormRenderConnection(formRecord, want.GetParams());
113 if (formRenderConnection == nullptr) {
114 HILOG_ERROR("null formRenderConnection");
115 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
116 }
117 ErrCode errorCode = ConnectRenderService(formRenderConnection, formRecord.privacyLevel);
118 if (errorCode != ERR_OK) {
119 HILOG_ERROR("ConnectServiceAbility failed");
120 FormRenderMgr::GetInstance().HandleConnectFailed(formRecord.formId, errorCode);
121 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
122 }
123 return ERR_OK;
124 }
125
CheckIfFormRecycled(FormRecord & formRecord,Want & want) const126 void FormRenderMgrInner::CheckIfFormRecycled(FormRecord &formRecord, Want& want) const
127 {
128 if (formRecord.recycleStatus == RecycleStatus::RECYCLED) {
129 formRecord.recycleStatus = RecycleStatus::NON_RECYCLABLE;
130 FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
131 std::string statusData;
132 if (FormInfoRdbStorageMgr::GetInstance().LoadStatusData(
133 std::to_string(formRecord.formId), statusData) != ERR_OK) {
134 HILOG_ERROR("read status data of %{public}" PRId64 " failed.", formRecord.formId);
135 } else {
136 want.SetParam(Constants::FORM_STATUS_DATA, statusData);
137 }
138 }
139 }
140
GetConnectionAndRenderForm(FormRecord & formRecord,Want & want)141 ErrCode FormRenderMgrInner::GetConnectionAndRenderForm(FormRecord &formRecord, Want &want)
142 {
143 std::lock_guard<std::mutex> lock(resourceMutex_);
144 auto conIterator = renderFormConnections_.find(formRecord.formId);
145 if (conIterator == renderFormConnections_.end()) {
146 HILOG_ERROR("Not find renderFormConnection");
147 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
148 }
149 auto connection = conIterator->second;
150 if (connection == nullptr) {
151 HILOG_ERROR("null connection");
152 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
153 }
154 sptr<IRemoteObject> remoteObject;
155 auto ret = GetRenderObject(remoteObject);
156 if (ret != ERR_OK) {
157 HILOG_ERROR("null remoteObjectGotten");
158 return ret;
159 }
160 CheckIfFormRecycled(formRecord, want);
161 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
162 FormTaskMgr::GetInstance().PostRenderForm(formRecord, std::move(want), remoteObject);
163 return ERR_OK;
164 }
165
UpdateRenderingForm(FormRecord & formRecord,const FormProviderData & formProviderData,const WantParams & wantParams,bool mergeData)166 ErrCode FormRenderMgrInner::UpdateRenderingForm(FormRecord &formRecord, const FormProviderData &formProviderData,
167 const WantParams &wantParams, bool mergeData)
168 {
169 if (mergeData) {
170 nlohmann::json jsonData = formProviderData.GetData();
171 formRecord.formProviderInfo.MergeData(jsonData);
172 auto providerData = formRecord.formProviderInfo.GetFormData();
173 providerData.SetImageDataState(formProviderData.GetImageDataState());
174 providerData.SetImageDataMap(formProviderData.GetImageDataMap());
175 formRecord.formProviderInfo.SetFormData(providerData);
176 } else {
177 formRecord.formProviderInfo.SetFormData(formProviderData);
178 }
179
180 if (formRecord.formProviderInfo.NeedCache()) {
181 FormCacheMgr::GetInstance().AddData(formRecord.formId, formRecord.formProviderInfo.GetFormData());
182 if (formRecord.recycleStatus != RecycleStatus::NON_RECYCLABLE) {
183 std::string cacheData;
184 std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap;
185 if (FormCacheMgr::GetInstance().GetData(formRecord.formId, cacheData, imageDataMap)) {
186 formRecord.formProviderInfo.SetImageDataMap(imageDataMap);
187 }
188 }
189 } else {
190 HILOG_DEBUG("need to delete data");
191 FormCacheMgr::GetInstance().DeleteData(formRecord.formId);
192 }
193 if (formRecord.isTimerRefresh) {
194 formRecord.isInited = true;
195 } else {
196 FormDataMgr::GetInstance().SetFormCacheInited(formRecord.formId, true);
197 }
198
199 HILOG_INFO("enableForm:%{public}d, protectForm:%{public}d", formRecord.enableForm, formRecord.protectForm);
200 if (!formRecord.enableForm) {
201 FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
202 FormDataMgr::GetInstance().SetUpdateDuringDisableForm(formRecord.formId, true);
203 return ERR_APPEXECFWK_FORM_DISABLE_REFRESH;
204 }
205 Want want;
206 want.SetParams(wantParams);
207 FillBundleInfo(want, formRecord.bundleName);
208 if (wantParams.IsEmpty()) {
209 want.SetParam(Constants::FORM_UPDATE_TYPE_KEY, Constants::ADAPTER_UPDATE_FORM);
210 }
211 want.SetParam(Constants::FORM_RENDER_TYPE_KEY, Constants::UPDATE_RENDERING_FORM);
212 std::string recordUid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
213 want.SetParam(Constants::FORM_SUPPLY_UID, recordUid);
214 return GetConnectionAndRenderForm(formRecord, want);
215 }
216
ReloadForm(const std::vector<FormRecord> && formRecords,const std::string & bundleName,int32_t userId)217 ErrCode FormRenderMgrInner::ReloadForm(
218 const std::vector<FormRecord> &&formRecords, const std::string &bundleName, int32_t userId)
219 {
220 sptr<IRemoteObject> remoteObject;
221 auto ret = GetRenderObject(remoteObject);
222 if (ret != ERR_OK) {
223 HILOG_ERROR("null remoteObjectGotten");
224 return ret;
225 }
226 Want want;
227 FillBundleInfo(want, bundleName);
228 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + bundleName);
229 FormTaskMgr::GetInstance().PostReloadForm(std::forward<decltype(formRecords)>(formRecords), want, remoteObject);
230 return ERR_OK;
231 }
232
FillBundleInfo(Want & want,const std::string & bundleName) const233 void FormRenderMgrInner::FillBundleInfo(Want &want, const std::string &bundleName) const
234 {
235 BundleInfo bundleInfo;
236 if (!FormBmsHelper::GetInstance().GetBundleInfoDefault(
237 bundleName, FormUtil::GetCurrentAccountId(), bundleInfo)) {
238 HILOG_ERROR("get bundle info failed. %{public}s", bundleName.c_str());
239 return;
240 }
241
242 want.SetParam(Constants::FORM_COMPATIBLE_VERSION_KEY, static_cast<int32_t>(bundleInfo.compatibleVersion));
243 want.SetParam(Constants::FORM_TARGET_VERSION_KEY, static_cast<int32_t>(bundleInfo.targetVersion));
244 }
245
PostOnUnlockTask()246 void FormRenderMgrInner::PostOnUnlockTask()
247 {
248 HILOG_DEBUG("call");
249 sptr<IRemoteObject> remoteObject;
250 auto ret = GetRenderObject(remoteObject);
251 if (ret != ERR_OK) {
252 HILOG_ERROR("null remoteObjectGotten");
253 return;
254 }
255 FormTaskMgr::GetInstance().PostOnUnlock(remoteObject);
256 }
257
NotifyScreenOn()258 void FormRenderMgrInner::NotifyScreenOn()
259 {
260 HILOG_DEBUG("call");
261 sptr<IRemoteObject> remoteObject;
262 auto ret = GetRenderObject(remoteObject);
263 if (ret != ERR_OK) {
264 HILOG_ERROR("null remoteObjectGotten");
265 return;
266 }
267 sptr<IFormRender> remoteFormRenderer = iface_cast<IFormRender>(remoteObject);
268 if (remoteFormRenderer == nullptr) {
269 return;
270 }
271 remoteFormRenderer->RunCachedConfigurationUpdated();
272 }
273
PostSetVisibleChangeTask(int64_t formId,bool isVisible)274 void FormRenderMgrInner::PostSetVisibleChangeTask(int64_t formId, bool isVisible)
275 {
276 HILOG_INFO("call");
277 sptr<IRemoteObject> remoteObject;
278 auto ret = GetRenderObject(remoteObject);
279 if (ret != ERR_OK) {
280 HILOG_ERROR("null remoteObjectGotten");
281 return;
282 }
283 FormTaskMgr::GetInstance().PostSetVisibleChange(formId, isVisible, remoteObject);
284 }
285
StopRenderingForm(int64_t formId,const FormRecord & formRecord,const std::string & compId,const sptr<IRemoteObject> & hostToken)286 ErrCode FormRenderMgrInner::StopRenderingForm(int64_t formId, const FormRecord &formRecord,
287 const std::string &compId, const sptr<IRemoteObject> &hostToken)
288 {
289 if (formRecord.uiSyntax != FormType::ETS) {
290 return ERR_OK;
291 }
292 if (formRecord.abilityName.empty()) {
293 HILOG_ERROR("empty formRecord.abilityName");
294 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
295 }
296 if (formRecord.bundleName.empty()) {
297 HILOG_ERROR("empty formRecord.bundleName");
298 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
299 }
300 Want want;
301 std::string recordUid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
302 want.SetParam(Constants::FORM_SUPPLY_UID, recordUid);
303 if (!compId.empty()) {
304 want.SetParam(Constants::FORM_RENDER_COMP_ID, compId);
305 }
306 if (hostToken) {
307 HILOG_DEBUG("StopRenderingForm Add host token");
308 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
309 }
310
311 {
312 std::lock_guard<std::mutex> lock(resourceMutex_);
313 auto conIterator = renderFormConnections_.find(formRecord.formId);
314 if (conIterator != renderFormConnections_.end()) {
315 auto connection = conIterator->second;
316 if (connection == nullptr) {
317 HILOG_ERROR("null connection");
318 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
319 }
320 sptr<IRemoteObject> remoteObject;
321 auto ret = GetRenderObject(remoteObject);
322 if (ret != ERR_OK) {
323 HILOG_ERROR("null remoteObjectGotten");
324 return ret;
325 }
326 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
327 FormTaskMgr::GetInstance().PostStopRenderingForm(formRecord, std::move(want), remoteObject);
328 return ERR_OK;
329 }
330 }
331 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
332 }
333
StopRenderingFormCallback(int64_t formId,const Want & want)334 ErrCode FormRenderMgrInner::StopRenderingFormCallback(int64_t formId, const Want &want)
335 {
336 size_t renderFormConnectionSize = 0;
337 sptr<FormRenderConnection> stopConnection = nullptr;
338 {
339 std::lock_guard<std::mutex> lock(resourceMutex_);
340 HILOG_DEBUG("renderFormConnections_ size:%{public}zu", renderFormConnections_.size());
341 auto conIterator = renderFormConnections_.find(formId);
342 if (conIterator == renderFormConnections_.end()) {
343 HILOG_ERROR("Can't find formId in map");
344 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
345 }
346 stopConnection = conIterator->second;
347 renderFormConnectionSize = renderFormConnections_.size();
348 for (auto iter = etsHosts_.begin(); iter != etsHosts_.end();) {
349 iter->second.erase(formId);
350 if (iter->second.empty()) {
351 HILOG_INFO("All forms of the host have been removed, remove the host");
352 iter = etsHosts_.erase(iter);
353 } else {
354 ++iter;
355 }
356 }
357 renderFormConnections_.erase(formId);
358 }
359 if (stopConnection == nullptr) {
360 HILOG_ERROR("Can't find stopConnection in map");
361 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
362 }
363 DisconnectRenderService(stopConnection, renderFormConnectionSize);
364 return ERR_OK;
365 }
366
ReleaseRenderer(int64_t formId,const FormRecord & formRecord,const std::string & compId)367 ErrCode FormRenderMgrInner::ReleaseRenderer(int64_t formId, const FormRecord &formRecord, const std::string &compId)
368 {
369 if (formRecord.uiSyntax != FormType::ETS) {
370 return ERR_OK;
371 }
372 if (formRecord.abilityName.empty()) {
373 HILOG_ERROR("empty formRecord.abilityName");
374 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
375 }
376 if (formRecord.bundleName.empty()) {
377 HILOG_ERROR("empty formRecord.bundleName");
378 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
379 }
380
381 std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
382 {
383 std::lock_guard<std::mutex> lock(resourceMutex_);
384 auto conIterator = renderFormConnections_.find(formRecord.formId);
385 if (conIterator != renderFormConnections_.end()) {
386 auto connection = conIterator->second;
387 if (connection == nullptr) {
388 HILOG_ERROR("null connection");
389 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
390 }
391 sptr<IRemoteObject> remoteObject;
392 auto ret = GetRenderObject(remoteObject);
393 if (ret != ERR_OK) {
394 HILOG_ERROR("null remoteObjectGotten");
395 return ret;
396 }
397 FormTaskMgr::GetInstance().PostReleaseRenderer(formId, compId, uid, remoteObject, formRecord.isDynamic);
398 return ERR_OK;
399 }
400 }
401 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
402 }
403
AddConnection(int64_t formId,sptr<FormRenderConnection> connection)404 ErrCode FormRenderMgrInner::AddConnection(int64_t formId, sptr<FormRenderConnection> connection)
405 {
406 if (connection == nullptr) {
407 HILOG_ERROR("null FormRenderConnection");
408 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
409 }
410 size_t renderFormConnectionSize = 0;
411 sptr<FormRenderConnection> oldConnection = nullptr;
412 {
413 std::lock_guard<std::mutex> lock(resourceMutex_);
414 int32_t connectKey = static_cast<int32_t>(FormUtil::GetCurrentMillisecond());
415 auto conIterator = renderFormConnections_.find(formId);
416 if (conIterator == renderFormConnections_.end()) {
417 connection->SetConnectId(connectKey);
418 renderFormConnections_.emplace(formId, connection);
419 } else if (renderFormConnections_[formId]->GetConnectId() != connection->GetConnectId()) {
420 HILOG_WARN("Duplicate connection of formId:%{public}" PRId64 ", delete old connection", formId);
421 renderFormConnectionSize = renderFormConnections_.size();
422 oldConnection = renderFormConnections_[formId];
423 renderFormConnections_[formId] = connection;
424 connection->SetConnectId(connectKey);
425 }
426 HILOG_DEBUG("renderFormConnections size:%{public}zu", renderFormConnections_.size());
427 }
428 if (oldConnection) {
429 DisconnectRenderService(oldConnection, renderFormConnectionSize);
430 }
431 return ERR_OK;
432 }
433
RemoveConnection(int64_t formId)434 void FormRenderMgrInner::RemoveConnection(int64_t formId)
435 {
436 std::lock_guard<std::mutex> lock(resourceMutex_);
437 if (renderFormConnections_.find(formId) != renderFormConnections_.end()) {
438 HILOG_DEBUG("Remove connection of formId:%{public}" PRId64 "", formId);
439 renderFormConnections_.erase(formId);
440 }
441 }
442
checkConnectionsFormIds(std::vector<int64_t> formIds,std::vector<int64_t> & needConFormIds)443 ErrCode FormRenderMgrInner::checkConnectionsFormIds(std::vector<int64_t> formIds, std::vector<int64_t> &needConFormIds)
444 {
445 HILOG_INFO("call");
446 std::lock_guard<std::mutex> lock(resourceMutex_);
447 for (const int64_t &formId : formIds) {
448 if (renderFormConnections_.find(formId) == renderFormConnections_.end()) {
449 HILOG_ERROR("need add connection of formId:%{public}" PRId64 "", formId);
450 needConFormIds.push_back(formId);
451 }
452 }
453 HILOG_INFO("end");
454 return ERR_OK;
455 }
456
RerenderAllForms()457 void FormRenderMgrInner::RerenderAllForms()
458 {
459 HILOG_INFO("FRS is died,notify host");
460 std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
461 renderRemoteObj_ = nullptr;
462 guard.unlock();
463 {
464 std::lock_guard<std::mutex> lock(resourceMutex_);
465 atomicRerenderCount_ = renderFormConnections_.size();
466 if (etsHosts_.empty() || renderFormConnections_.empty()) {
467 HILOG_INFO("All hosts died or all connections erased, no need to rerender");
468 return;
469 }
470 HILOG_INFO("The forms need to rerender count:%{public}zu", renderFormConnections_.size());
471 for (auto &item : renderFormConnections_) {
472 if (item.second == nullptr) {
473 HILOG_ERROR("null Connection");
474 continue;
475 }
476 item.second->SetStateDisconnected();
477 FormStatusMgr::GetInstance().ResetFormStatus(item.first);
478 }
479 }
480
481 NotifyHostRenderServiceIsDead();
482 }
483
CleanFormHost(const sptr<IRemoteObject> & host)484 void FormRenderMgrInner::CleanFormHost(const sptr<IRemoteObject> &host)
485 {
486 HILOG_INFO("Host is died or been removed, notify FormRenderService and remove host");
487 RemoveHostToken(host);
488 std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
489 if (renderRemoteObj_ == nullptr) {
490 HILOG_WARN("renderRemoteObj is null,render service may exit already");
491 return;
492 }
493 renderRemoteObj_->CleanFormHost(host);
494 }
495
AddRenderDeathRecipient(const sptr<IRemoteObject> & remoteObject)496 void FormRenderMgrInner::AddRenderDeathRecipient(const sptr<IRemoteObject> &remoteObject)
497 {
498 std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
499 if (renderRemoteObj_) {
500 HILOG_INFO("renderDeathRecipient is exist, no need to add again");
501 return;
502 }
503 guard.unlock();
504
505 HILOG_INFO("Get renderRemoteObj,add death recipient");
506 auto renderRemoteObj = iface_cast<IFormRender>(remoteObject);
507 if (renderRemoteObj == nullptr) {
508 HILOG_ERROR("null renderRemoteObj");
509 return;
510 }
511
512 if (renderDeathRecipient_ == nullptr) {
513 renderDeathRecipient_ = new (std::nothrow) FormRenderRecipient([this]() {
514 HILOG_WARN("FRS is Death, userId:%{public}d, isActiveUser:%{public}d", userId_, isActiveUser_);
515 if (isActiveUser_) {
516 RerenderAllForms();
517 } else {
518 std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
519 renderRemoteObj_ = nullptr;
520 guard.unlock();
521 }
522 });
523 }
524 if (!remoteObject->AddDeathRecipient(renderDeathRecipient_)) {
525 HILOG_ERROR("AddDeathRecipient failed");
526 return;
527 }
528 SetRenderRemoteObj(renderRemoteObj);
529 }
530
ConnectRenderService(const sptr<FormRenderConnection> & connection,int32_t level) const531 inline ErrCode FormRenderMgrInner::ConnectRenderService(
532 const sptr<FormRenderConnection> &connection, int32_t level) const
533 {
534 if (connection == nullptr) {
535 HILOG_INFO("null connection");
536 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
537 }
538 Want want;
539 want.SetElementName(Constants::FRS_BUNDLE_NAME, "ServiceExtension");
540 want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
541 if (level > 0) {
542 want.SetParam(DLP_INDEX, Constants::DEFAULT_SANDBOX_FRS_APP_INDEX);
543 want.SetParam(Constants::FRS_APP_INDEX, Constants::DEFAULT_SANDBOX_FRS_APP_INDEX);
544 }
545 connection->SetStateConnecting();
546 return FormAmsHelper::GetInstance().ConnectServiceAbilityWithUserId(want, connection, GetUserId());
547 }
548
SetUserId(int32_t userId)549 void FormRenderMgrInner::SetUserId(int32_t userId)
550 {
551 userId_ = userId;
552 }
553
GetUserId() const554 int32_t FormRenderMgrInner::GetUserId() const
555 {
556 return userId_;
557 }
558
RerenderAllFormsImmediate()559 void FormRenderMgrInner::RerenderAllFormsImmediate()
560 {
561 HILOG_INFO("Called");
562 isActiveUser_ = true;
563 if (etsHosts_.empty()) {
564 HILOG_WARN("All hosts died, no need to rerender.");
565 return;
566 }
567 NotifyHostRenderServiceIsDead();
568 }
569
DisconnectAllRenderConnections()570 void FormRenderMgrInner::DisconnectAllRenderConnections()
571 {
572 HILOG_INFO("renderFormConnections size: %{public}zu.", renderFormConnections_.size());
573 std::lock_guard<std::mutex> lock(resourceMutex_);
574 size_t size = renderFormConnections_.size();
575 for (auto iter = renderFormConnections_.begin(); iter != renderFormConnections_.end();) {
576 DisconnectRenderService(iter->second, size);
577 iter = renderFormConnections_.erase(iter);
578 size--;
579 }
580 isActiveUser_ = false;
581 }
582
DisconnectRenderService(const sptr<FormRenderConnection> connection,size_t size) const583 void FormRenderMgrInner::DisconnectRenderService(const sptr<FormRenderConnection> connection, size_t size) const
584 {
585 if (size == LAST_CONNECTION) {
586 HILOG_INFO("This is the last connection, disconnect render service delay");
587 FormAmsHelper::GetInstance().DisconnectServiceAbilityDelay(connection, FORM_DISCONNECT_FRS_DELAY_TIME);
588 } else {
589 HILOG_DEBUG("Disconnect render service ability");
590 FormAmsHelper::GetInstance().DisconnectServiceAbility(connection);
591 }
592 }
593
OnRenderingBlock(const std::string & bundleName)594 void FormRenderMgrInner::OnRenderingBlock(const std::string &bundleName)
595 {
596 HILOG_INFO("bundleName:%{public}s", bundleName.c_str());
597 FormEventInfo eventInfo;
598 eventInfo.bundleName = bundleName;
599 FormEventReport::SendSecondFormEvent(
600 FormEventName::FORM_RENDER_BLOCK, HiSysEventType::FAULT, eventInfo);
601
602 FormTrustMgr::GetInstance().MarkTrustFlag(bundleName, false);
603
604 Want want;
605 want.SetElementName(Constants::FRS_BUNDLE_NAME, "ServiceExtension");
606 want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
607 FormAmsHelper::GetInstance().StopExtensionAbility(want);
608 }
609
AddHostToken(const sptr<IRemoteObject> & host,int64_t formId)610 inline void FormRenderMgrInner::AddHostToken(const sptr<IRemoteObject> &host, int64_t formId)
611 {
612 std::lock_guard<std::mutex> lock(resourceMutex_);
613 auto iter = etsHosts_.find(host);
614 if (iter == etsHosts_.end()) {
615 HILOG_DEBUG("Add host, current etsHosts.size:%{public}zu", etsHosts_.size());
616 std::unordered_set<int64_t> formIdSet;
617 formIdSet.emplace(formId);
618 etsHosts_.emplace(host, formIdSet);
619 } else {
620 HILOG_DEBUG("Add formId to host, current etsHosts.size:%{public}zu", etsHosts_.size());
621 iter->second.emplace(formId);
622 }
623 }
624
RemoveHostToken(const sptr<IRemoteObject> & host)625 void FormRenderMgrInner::RemoveHostToken(const sptr<IRemoteObject> &host)
626 {
627 size_t left = 0;
628 std::unordered_map<int64_t, sptr<FormRenderConnection>> connections;
629 {
630 std::lock_guard<std::mutex> lock(resourceMutex_);
631 auto iter = etsHosts_.find(host);
632 if (iter == etsHosts_.end()) {
633 HILOG_ERROR("Can't find host in etsHosts");
634 return;
635 }
636 auto formIdSet = iter->second;
637 etsHosts_.erase(host);
638 if (etsHosts_.empty()) {
639 HILOG_DEBUG("etsHosts is empty, disconnect all connections size:%{public}zu",
640 renderFormConnections_.size());
641 connections.swap(renderFormConnections_);
642 } else {
643 for (const int64_t formId : formIdSet) {
644 FormRecord formRecord;
645 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
646 connections.emplace(formId, renderFormConnections_[formId]);
647 renderFormConnections_.erase(formId);
648 }
649 }
650 }
651 left = renderFormConnections_.size();
652 }
653 for (auto iter = connections.begin(); iter != connections.end();) {
654 DisconnectRenderService(iter->second, connections.size() > left ? connections.size() : left);
655 iter = connections.erase(iter);
656 }
657 }
658
NotifyHostRenderServiceIsDead() const659 void FormRenderMgrInner::NotifyHostRenderServiceIsDead() const
660 {
661 std::unordered_map<sptr<IRemoteObject>, std::unordered_set<int64_t>, RemoteObjHash> hostsForNotify;
662 {
663 std::lock_guard<std::mutex> lock(resourceMutex_);
664 HILOG_INFO("Notify hosts the render is dead, hosts.size:%{public}zu", etsHosts_.size());
665 auto tmpMap(etsHosts_);
666 hostsForNotify.swap(tmpMap);
667 }
668 for (const auto &item : hostsForNotify) {
669 sptr<IRemoteObject> hostClient = item.first;
670 if (hostClient == nullptr) {
671 HILOG_ERROR("null hostClient");
672 continue;
673 }
674 FormTaskMgr::GetInstance().PostFrsDiedTaskToHost(hostClient);
675 }
676 }
677
GetRenderRemoteObj() const678 sptr<IFormRender> FormRenderMgrInner::GetRenderRemoteObj() const
679 {
680 return renderRemoteObj_;
681 }
682
SetRenderRemoteObj(sptr<IFormRender> remoteObject)683 void FormRenderMgrInner::SetRenderRemoteObj(sptr<IFormRender> remoteObject)
684 {
685 std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
686 renderRemoteObj_ = remoteObject;
687 }
688
GetReRenderCount() const689 int32_t FormRenderMgrInner::GetReRenderCount() const
690 {
691 return atomicRerenderCount_;
692 }
693
RecycleForms(const std::vector<int64_t> & formIds,const Want & want,const sptr<IRemoteObject> & remoteObjectOfHost)694 ErrCode FormRenderMgrInner::RecycleForms(
695 const std::vector<int64_t> &formIds, const Want &want, const sptr<IRemoteObject> &remoteObjectOfHost)
696 {
697 HILOG_DEBUG("call");
698 sptr<IRemoteObject> remoteObject;
699 auto ret = GetRenderObject(remoteObject);
700 if (ret != ERR_OK) {
701 HILOG_ERROR("null remoteObjectGotten");
702 return ret;
703 }
704
705 std::lock_guard<std::mutex> lock(resourceMutex_);
706 std::vector<int64_t> connectedForms;
707 for (const int64_t &formId : formIds) {
708 auto conIterator = renderFormConnections_.find(formId);
709 if (conIterator != renderFormConnections_.end()) {
710 auto connection = conIterator->second;
711 if (connection == nullptr) {
712 HILOG_ERROR("connection of %{public}" PRId64 " is null.", formId);
713 continue;
714 }
715 connectedForms.emplace_back(formId);
716 } else {
717 HILOG_ERROR("can't find connection of %{public}" PRId64, formId);
718 }
719 }
720 FormTaskMgr::GetInstance().PostRecycleForms(connectedForms, want, remoteObjectOfHost, remoteObject);
721 return ERR_OK;
722 }
723
RecoverForms(const std::vector<int64_t> & formIds,const WantParams & wantParams)724 ErrCode FormRenderMgrInner::RecoverForms(const std::vector<int64_t> &formIds, const WantParams &wantParams)
725 {
726 HILOG_DEBUG("call");
727 sptr<IRemoteObject> remoteObject;
728 auto ret = GetRenderObject(remoteObject);
729 if (ret != ERR_OK) {
730 HILOG_ERROR("null remoteObjectGotten");
731 return ret;
732 }
733
734 for (const int64_t &formId : formIds) {
735 Want want;
736 want.SetParams(wantParams);
737
738 FormRecord formRecord;
739 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
740 HILOG_ERROR("form record %{public}" PRId64 " not exist", formId);
741 continue;
742 }
743
744 std::string cacheData;
745 std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap;
746 if (FormCacheMgr::GetInstance().GetData(formRecord.formId, cacheData, imageDataMap)) {
747 formRecord.formProviderInfo.SetImageDataMap(imageDataMap);
748 }
749
750 std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
751 want.SetParam(Constants::FORM_SUPPLY_UID, uid);
752
753 std::lock_guard<std::mutex> lock(resourceMutex_);
754 auto conIterator = renderFormConnections_.find(formId);
755 if (conIterator != renderFormConnections_.end()) {
756 auto connection = conIterator->second;
757 if (connection == nullptr) {
758 HILOG_ERROR("connection of %{public}" PRId64 " is null.", formId);
759 continue;
760 }
761 want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
762
763 std::string statusData;
764 if (FormInfoRdbStorageMgr::GetInstance().LoadStatusData(std::to_string(formId), statusData) != ERR_OK) {
765 HILOG_ERROR("read status data of %{public}" PRId64 " failed.", formId);
766 }
767 want.SetParam(Constants::FORM_STATUS_DATA, statusData);
768
769 FormTaskMgr::GetInstance().PostRecoverForm(formRecord, want, remoteObject);
770 } else {
771 HILOG_ERROR("can't find connection of %{public}" PRId64, formId);
772 }
773 }
774 return ERR_OK;
775 }
776
UpdateFormSize(const int64_t & formId,float width,float height,float borderWidth)777 ErrCode FormRenderMgrInner::UpdateFormSize(const int64_t &formId, float width, float height, float borderWidth)
778 {
779 HILOG_DEBUG("call");
780 sptr<IRemoteObject> remoteObject;
781 auto ret = GetRenderObject(remoteObject);
782 if (ret != ERR_OK) {
783 HILOG_ERROR("null remoteObjectGotten");
784 return ret;
785 }
786
787 FormRecord formRecord;
788 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
789 HILOG_ERROR("form record %{public}" PRId64 " not exist", formId);
790 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
791 }
792 std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
793 FormTaskMgr::GetInstance().PostUpdateFormSize(formId, width, height, borderWidth, uid, remoteObject);
794 return ERR_OK;
795 }
796
GetRenderObject(sptr<IRemoteObject> & renderObj)797 ErrCode FormRenderMgrInner::GetRenderObject(sptr<IRemoteObject> &renderObj)
798 {
799 std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
800 if (renderRemoteObj_ == nullptr) {
801 HILOG_ERROR("null renderRemoteObj");
802 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
803 }
804 renderObj = renderRemoteObj_->AsObject();
805 if (renderObj == nullptr) {
806 HILOG_ERROR("null remoteObj");
807 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
808 }
809 return ERR_OK;
810 }
811
OnRemoteDied(const wptr<IRemoteObject> & remote)812 void FormRenderRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
813 {
814 HILOG_INFO("Recv FormRenderService death notice");
815 if (handler_) {
816 handler_();
817 }
818 }
819
FormRenderRecipient(RemoteDiedHandler handler)820 FormRenderRecipient::FormRenderRecipient(RemoteDiedHandler handler) : handler_(handler) {}
821
~FormRenderRecipient()822 FormRenderRecipient::~FormRenderRecipient() {}
823 } // namespace AppExecFwk
824 } // namespace OHOS
825