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