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