• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "form_render_mgr_inner.h"
17 
18 #include <mutex>
19 
20 #include "form_render_mgr.h"
21 #include "fms_log_wrapper.h"
22 #include "form_ams_helper.h"
23 #include "form_bms_helper.h"
24 #include "form_cache_mgr.h"
25 #include "form_constants.h"
26 #include "form_data_mgr.h"
27 #include "form_event_report.h"
28 #include "form_host_interface.h"
29 #include "form_mgr_errors.h"
30 #include "form_render_mgr.h"
31 #include "form_supply_callback.h"
32 #include "form_task_mgr.h"
33 #include "form_trust_mgr.h"
34 #include "form_util.h"
35 #include "ipc_skeleton.h"
36 #include "os_account_manager.h"
37 #include "want.h"
38 #include "form_info_rdb_storage_mgr.h"
39 
40 namespace OHOS {
41 namespace AppExecFwk {
42 namespace {
43 constexpr size_t LAST_CONNECTION = 1;
44 const std::string DLP_INDEX = "ohos.dlp.params.index";
45 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