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