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