• 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/form_render_mgr_inner.h"
17 
18 #include <mutex>
19 
20 #include "form_render/form_render_mgr.h"
21 #include "fms_log_wrapper.h"
22 #include "ams_mgr/form_ams_helper.h"
23 #include "bms_mgr/form_bms_helper.h"
24 #include "data_center/form_cache_mgr.h"
25 #include "form_constants.h"
26 #include "data_center/form_data_mgr.h"
27 #include "common/event/form_event_report.h"
28 #include "form_host_interface.h"
29 #include "form_mgr_errors.h"
30 #include "form_render/form_render_task_mgr.h"
31 #include "form_provider/form_supply_callback.h"
32 #include "status_mgr_center/form_status_task_mgr.h"
33 #include "common/util/form_trust_mgr.h"
34 #include "common/util/form_util.h"
35 #include "ipc_skeleton.h"
36 #include "os_account_manager.h"
37 #include "want.h"
38 #include "data_center/form_info/form_info_rdb_storage_mgr.h"
39 #include "data_center/form_record/form_record_report.h"
40 #include "status_mgr_center/form_status_mgr.h"
41 #include "form_host/form_host_task_mgr.h"
42 #include "status_mgr_center/form_status.h"
43 #include "form_refresh/strategy/refresh_cache_mgr.h"
44 #include "feature/memory_mgr/form_render_report.h"
45 
46 namespace OHOS {
47 namespace AppExecFwk {
48 namespace {
49 constexpr size_t LAST_CONNECTION = 1;
50 const std::string DLP_INDEX = "ohos.dlp.params.index";
51 const int FORM_DISCONNECT_FRS_DELAY_TIME = 5000; // ms
52 }
53 using Want = OHOS::AAFwk::Want;
FormRenderMgrInner()54 FormRenderMgrInner::FormRenderMgrInner()
55 {
56 }
~FormRenderMgrInner()57 FormRenderMgrInner::~FormRenderMgrInner()
58 {
59 }
60 
RenderForm(const FormRecord & formRecord,Want & want,const sptr<IRemoteObject> & hostToken)61 ErrCode FormRenderMgrInner::RenderForm(
62     const FormRecord &formRecord, Want &want, const sptr<IRemoteObject> &hostToken)
63 {
64     RecoverFRSOnFormActivity();
65     if (atomicRerenderCount_ > 0) {
66         --atomicRerenderCount_;
67     } else {
68         atomicRerenderCount_ = 0;
69     }
70     if (hostToken) {
71         HILOG_DEBUG("Add host token");
72         AddHostToken(hostToken, formRecord.formId);
73         want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
74     }
75     if (!isActiveUser_) {
76         HILOG_WARN("isActiveUser is false, return");
77         return ERR_APPEXECFWK_FORM_RENDER_SERVICE_DIED;
78     }
79     FillBundleInfo(want, formRecord.bundleName);
80 
81     sptr<FormRenderConnection> connection = nullptr;
82     bool connectionExisted = GetRenderFormConnection(connection, formRecord.formId);
83     if (connectionExisted) {
84         if (connection == nullptr) {
85             HILOG_ERROR("null connection");
86             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
87         }
88         return RenderConnectedForm(formRecord, want, connection);
89     }
90 
91     auto formRenderConnection = new (std::nothrow) FormRenderConnection(formRecord, want.GetParams());
92     if (formRenderConnection == nullptr) {
93         HILOG_ERROR("null formRenderConnection");
94         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
95     }
96     ErrCode errorCode = ConnectRenderService(formRenderConnection, formRecord.privacyLevel);
97     if (errorCode != ERR_OK) {
98         HILOG_ERROR("ConnectServiceAbility failed");
99         FormRenderMgr::GetInstance().HandleConnectFailed(formRecord.formId, errorCode);
100         FormEventReport::SendFormFailedEvent(FormEventName::ADD_FORM_FAILED,
101             formRecord.formId,
102             formRecord.bundleName,
103             formRecord.formName,
104             static_cast<int32_t>(AddFormFiledErrorType::CONNECT_FORM_RENDER_FAILED));
105         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
106     }
107     return ERR_OK;
108 }
109 
CheckIfFormRecycled(FormRecord & formRecord,Want & want) const110 void FormRenderMgrInner::CheckIfFormRecycled(FormRecord &formRecord, Want& want) const
111 {
112     if (FormStatus::GetInstance().GetFormStatus(formRecord.formId) == FormFsmStatus::RECYCLED) {
113         formRecord.recycleStatus = RecycleStatus::NON_RECYCLABLE;
114         FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
115         std::string statusData;
116         if (FormInfoRdbStorageMgr::GetInstance().LoadStatusData(
117             std::to_string(formRecord.formId), statusData) != ERR_OK) {
118             HILOG_ERROR("read status data of %{public}" PRId64 " failed.", formRecord.formId);
119         } else {
120             want.SetParam(Constants::FORM_STATUS_DATA, statusData);
121         }
122     }
123 }
124 
GetConnectionAndRenderForm(FormRecord & formRecord,Want & want)125 ErrCode FormRenderMgrInner::GetConnectionAndRenderForm(FormRecord &formRecord, Want &want)
126 {
127     int32_t connectId = 0;
128     if (!GetRenderFormConnectId(formRecord.formId, connectId)) {
129         HILOG_ERROR("Not find renderFormConnection");
130         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
131     }
132     sptr<IRemoteObject> remoteObject;
133     auto ret = GetRenderObject(remoteObject);
134     if (ret != ERR_OK) {
135         HILOG_ERROR("null remoteObjectGotten");
136         return ret;
137     }
138     CheckIfFormRecycled(formRecord, want);
139     want.SetParam(Constants::FORM_CONNECT_ID, connectId);
140 
141     auto renderType = want.GetIntParam(Constants::FORM_UPDATE_TYPE_KEY, Constants::ADD_FORM_UPDATE_FORM);
142     if (renderType != Constants::ADAPTER_UPDATE_FORM ||
143         FormDataMgr::GetInstance().GetFormCanUpdate(formRecord.formId) ||
144         FormDataMgr::GetInstance().IsDataProxyIgnoreFormVisibility(formRecord.formId)) {
145         FormDataMgr::GetInstance().ResetDataProxyUpdate(formRecord.formId);
146         FormStatusTaskMgr::GetInstance().PostRenderForm(formRecord, std::move(want), remoteObject);
147         return ERR_OK;
148     }
149 
150     auto task = [formRecord, newWant = want, remoteObject]() {
151         FormRecord newRecord(formRecord);
152         std::string cacheData;
153         std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap;
154         bool hasCacheData = FormCacheMgr::GetInstance().GetData(formRecord.formId, cacheData, imageDataMap);
155         if (hasCacheData) {
156             newRecord.formProviderInfo.SetFormDataString(cacheData);
157             newRecord.formProviderInfo.SetImageDataMap(imageDataMap);
158         }
159         FormStatusTaskMgr::GetInstance().PostRenderForm(newRecord, newWant, remoteObject);
160     };
161     RefreshCacheMgr::GetInstance().AddRenderTask(formRecord.formId, task);
162     return ERR_OK;
163 }
164 
UpdateRenderingForm(FormRecord & formRecord,const FormProviderData & formProviderData,const WantParams & wantParams,bool mergeData)165 ErrCode FormRenderMgrInner::UpdateRenderingForm(FormRecord &formRecord, const FormProviderData &formProviderData,
166     const WantParams &wantParams, bool mergeData)
167 {
168     RecoverFRSOnFormActivity();
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 (FormStatus::GetInstance().GetFormStatus(formRecord.formId) == FormFsmStatus::RECYCLED) {
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         FormRecordReport::GetInstance().IncreaseUpdateTimes(formRecord.formId,
204             HiSysEventPointType::TYPE_DISABLE_FORM_INTERCEPT);
205         return ERR_APPEXECFWK_FORM_DISABLE_REFRESH;
206     }
207     Want want;
208     want.SetParams(wantParams);
209     FillBundleInfo(want, formRecord.bundleName);
210     if (wantParams.IsEmpty()) {
211         want.SetParam(Constants::FORM_UPDATE_TYPE_KEY, Constants::ADAPTER_UPDATE_FORM);
212     }
213     want.SetParam(Constants::FORM_RENDER_TYPE_KEY, Constants::UPDATE_RENDERING_FORM);
214     std::string recordUid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
215     want.SetParam(Constants::FORM_SUPPLY_UID, recordUid);
216     want.SetParam(Constants::FORM_LOCATION_KEY, static_cast<int32_t>(formRecord.formLocation));
217     return GetConnectionAndRenderForm(formRecord, want);
218 }
219 
ReloadForm(const std::vector<FormRecord> && formRecords,const std::string & bundleName,int32_t userId)220 ErrCode FormRenderMgrInner::ReloadForm(
221     const std::vector<FormRecord> &&formRecords, const std::string &bundleName, int32_t userId)
222 {
223     RecoverFRSOnFormActivity();
224     sptr<IRemoteObject> remoteObject;
225     auto ret = GetRenderObject(remoteObject);
226     if (ret != ERR_OK) {
227         HILOG_ERROR("null remoteObjectGotten");
228         return ret;
229     }
230     Want want;
231     FillBundleInfo(want, bundleName);
232     want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(userId) + bundleName);
233     want.SetParam(Constants::PARAM_BUNDLE_NAME_KEY, bundleName);
234     FormRenderTaskMgr::GetInstance().PostReloadForm(std::forward<decltype(formRecords)>(formRecords),
235         want, remoteObject);
236     return ERR_OK;
237 }
238 
FillBundleInfo(Want & want,const std::string & bundleName) const239 void FormRenderMgrInner::FillBundleInfo(Want &want, const std::string &bundleName) const
240 {
241     BundleInfo bundleInfo;
242     if (!FormBmsHelper::GetInstance().GetBundleInfoDefault(
243         bundleName, FormUtil::GetCurrentAccountId(), bundleInfo)) {
244         HILOG_ERROR("get bundle info failed. %{public}s", bundleName.c_str());
245         return;
246     }
247 
248     want.SetParam(Constants::FORM_COMPATIBLE_VERSION_KEY, static_cast<int32_t>(bundleInfo.compatibleVersion));
249     want.SetParam(Constants::FORM_TARGET_VERSION_KEY, static_cast<int32_t>(bundleInfo.targetVersion));
250 }
251 
PostOnUnlockTask()252 void FormRenderMgrInner::PostOnUnlockTask()
253 {
254     HILOG_DEBUG("call");
255     RecoverFRSOnFormActivity();
256     sptr<IRemoteObject> remoteObject;
257     auto ret = GetRenderObject(remoteObject);
258     if (ret != ERR_OK) {
259         HILOG_ERROR("null remoteObjectGotten");
260         return;
261     }
262     FormRenderTaskMgr::GetInstance().PostOnUnlock(remoteObject);
263 }
264 
NotifyScreenOn()265 void FormRenderMgrInner::NotifyScreenOn()
266 {
267     HILOG_DEBUG("call");
268     RecoverFRSOnFormActivity();
269     sptr<IRemoteObject> remoteObject;
270     auto ret = GetRenderObject(remoteObject);
271     if (ret != ERR_OK) {
272         HILOG_ERROR("null remoteObjectGotten");
273         return;
274     }
275     sptr<IFormRender> remoteFormRenderer = iface_cast<IFormRender>(remoteObject);
276     if (remoteFormRenderer == nullptr) {
277         return;
278     }
279     remoteFormRenderer->RunCachedConfigurationUpdated();
280 }
281 
PostSetVisibleChangeTask(int64_t formId,bool isVisible)282 void FormRenderMgrInner::PostSetVisibleChangeTask(int64_t formId, bool isVisible)
283 {
284     HILOG_INFO("call");
285     if (isVisible) {
286         RecoverFRSOnFormActivity();
287     }
288     sptr<IRemoteObject> remoteObject;
289     auto ret = GetRenderObject(remoteObject);
290     if (ret != ERR_OK) {
291         HILOG_ERROR("null remoteObjectGotten");
292         return;
293     }
294     FormRenderTaskMgr::GetInstance().PostSetVisibleChange(formId, isVisible, remoteObject);
295 }
296 
StopRenderingForm(int64_t formId,const FormRecord & formRecord,const std::string & compId,const sptr<IRemoteObject> & hostToken)297 ErrCode FormRenderMgrInner::StopRenderingForm(int64_t formId, const FormRecord &formRecord,
298     const std::string &compId, const sptr<IRemoteObject> &hostToken)
299 {
300     if (formRecord.uiSyntax != FormType::ETS) {
301         return ERR_OK;
302     }
303     if (formRecord.abilityName.empty()) {
304         HILOG_ERROR("empty formRecord.abilityName");
305         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
306     }
307     if (formRecord.bundleName.empty()) {
308         HILOG_ERROR("empty formRecord.bundleName");
309         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
310     }
311     RecoverFRSOnFormActivity();
312     Want want;
313     std::string recordUid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
314     want.SetParam(Constants::FORM_SUPPLY_UID, recordUid);
315     if (!compId.empty()) {
316         want.SetParam(Constants::FORM_RENDER_COMP_ID, compId);
317     }
318     if (hostToken) {
319         HILOG_DEBUG("StopRenderingForm Add host token");
320         want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
321     }
322 
323     return PostStopRenderingFormTask(formRecord, want);
324 }
325 
StopRenderingFormCallback(int64_t formId,const Want & want)326 ErrCode FormRenderMgrInner::StopRenderingFormCallback(int64_t formId, const Want &want)
327 {
328     size_t renderFormConnectionSize = 0;
329     sptr<FormRenderConnection> stopConnection = nullptr;
330     {
331         std::lock_guard<std::mutex> lock(resourceMutex_);
332         HILOG_DEBUG("renderFormConnections_ size:%{public}zu", renderFormConnections_.size());
333         auto conIterator = renderFormConnections_.find(formId);
334         if (conIterator == renderFormConnections_.end()) {
335             HILOG_ERROR("Can't find formId in map");
336             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
337         }
338         stopConnection = conIterator->second;
339         renderFormConnectionSize = renderFormConnections_.size();
340         for (auto iter = etsHosts_.begin(); iter != etsHosts_.end();) {
341             iter->second.erase(formId);
342             if (iter->second.empty()) {
343                 HILOG_INFO("All forms of the host have been removed, remove the host");
344                 iter = etsHosts_.erase(iter);
345             } else {
346                 ++iter;
347             }
348         }
349         renderFormConnections_.erase(formId);
350     }
351     if (stopConnection == nullptr) {
352         HILOG_ERROR("Can't find stopConnection in map");
353         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
354     }
355     DisconnectRenderService(stopConnection, renderFormConnectionSize);
356     return ERR_OK;
357 }
358 
ReleaseRenderer(int64_t formId,const FormRecord & formRecord,const std::string & compId)359 ErrCode FormRenderMgrInner::ReleaseRenderer(int64_t formId, const FormRecord &formRecord, const std::string &compId)
360 {
361     if (formRecord.uiSyntax != FormType::ETS) {
362         return ERR_OK;
363     }
364     if (formRecord.abilityName.empty()) {
365         HILOG_ERROR("empty formRecord.abilityName");
366         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
367     }
368     if (formRecord.bundleName.empty()) {
369         HILOG_ERROR("empty formRecord.bundleName");
370         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
371     }
372 
373     if (CheckRenderConnectionExistById(formRecord.formId) != ERR_OK) {
374         HILOG_ERROR("null connection");
375         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
376     }
377     RecoverFRSOnFormActivity();
378     sptr<IRemoteObject> remoteObject;
379     auto ret = GetRenderObject(remoteObject);
380     if (ret != ERR_OK) {
381         HILOG_ERROR("null remoteObjectGotten");
382         return ret;
383     }
384     std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
385     FormStatusTaskMgr::GetInstance().PostReleaseRenderer(formId, compId, uid, remoteObject, formRecord.isDynamic);
386     return ERR_OK;
387 }
388 
AddConnection(int64_t formId,sptr<FormRenderConnection> connection)389 ErrCode FormRenderMgrInner::AddConnection(int64_t formId, sptr<FormRenderConnection> connection)
390 {
391     if (connection == nullptr) {
392         HILOG_ERROR("null FormRenderConnection");
393         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
394     }
395     size_t renderFormConnectionSize = 0;
396     sptr<FormRenderConnection> oldConnection = nullptr;
397     {
398         std::lock_guard<std::mutex> lock(resourceMutex_);
399         int32_t connectKey = static_cast<int32_t>(FormUtil::GetCurrentMillisecond());
400         auto conIterator = renderFormConnections_.find(formId);
401         if (conIterator == renderFormConnections_.end()) {
402             connection->SetConnectId(connectKey);
403             renderFormConnections_.emplace(formId, connection);
404         } else if (renderFormConnections_[formId]->GetConnectId() != connection->GetConnectId()) {
405             HILOG_WARN("Duplicate connection of formId:%{public}" PRId64 ", delete old connection", formId);
406             renderFormConnectionSize = renderFormConnections_.size();
407             oldConnection = renderFormConnections_[formId];
408             renderFormConnections_[formId] = connection;
409             connection->SetConnectId(connectKey);
410         }
411         HILOG_DEBUG("renderFormConnections size:%{public}zu", renderFormConnections_.size());
412     }
413     if (oldConnection) {
414         DisconnectRenderService(oldConnection, renderFormConnectionSize);
415     }
416     return ERR_OK;
417 }
418 
RemoveConnection(int64_t formId)419 void FormRenderMgrInner::RemoveConnection(int64_t formId)
420 {
421     std::lock_guard<std::mutex> lock(resourceMutex_);
422     if (renderFormConnections_.find(formId) != renderFormConnections_.end()) {
423         HILOG_DEBUG("Remove connection of formId:%{public}" PRId64 "", formId);
424         renderFormConnections_.erase(formId);
425     }
426 }
427 
checkConnectionsFormIds(std::vector<int64_t> formIds,std::vector<int64_t> & needConFormIds)428 ErrCode FormRenderMgrInner::checkConnectionsFormIds(std::vector<int64_t> formIds, std::vector<int64_t> &needConFormIds)
429 {
430     HILOG_INFO("call");
431     std::lock_guard<std::mutex> lock(resourceMutex_);
432     for (const int64_t &formId : formIds) {
433         if (renderFormConnections_.find(formId) == renderFormConnections_.end()) {
434             HILOG_ERROR("need add connection of formId:%{public}" PRId64 "", formId);
435             needConFormIds.push_back(formId);
436         }
437     }
438     HILOG_INFO("end");
439     return ERR_OK;
440 }
441 
RerenderAllForms()442 void FormRenderMgrInner::RerenderAllForms()
443 {
444     HILOG_WARN("FRS is died,notify host");
445     std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
446     renderRemoteObj_ = nullptr;
447     guard.unlock();
448     {
449         std::lock_guard<std::mutex> lock(resourceMutex_);
450         atomicRerenderCount_ = renderFormConnections_.size();
451         if (etsHosts_.empty() || renderFormConnections_.empty()) {
452             HILOG_INFO("All hosts died or all connections erased, no need to rerender");
453             return;
454         }
455         HILOG_INFO("The forms need to rerender count:%{public}zu", renderFormConnections_.size());
456         for (auto &item : renderFormConnections_) {
457             if (item.second == nullptr) {
458                 HILOG_ERROR("null Connection");
459                 continue;
460             }
461             item.second->SetStateDisconnected();
462         }
463     }
464     if (!FormDataMgr::GetInstance().IsLowMemory()) {
465         NotifyHostRenderServiceIsDead();
466     } else {
467         FormRenderReport::GetInstance().RecordFRSDead();
468         isFrsDiedInLowMemory_ = true;
469         HILOG_ERROR("Low memory killed FRS");
470     }
471 }
472 
CleanFormHost(const sptr<IRemoteObject> & host)473 void FormRenderMgrInner::CleanFormHost(const sptr<IRemoteObject> &host)
474 {
475     HILOG_INFO("Host is died or been removed, notify FormRenderService and remove host");
476     RemoveHostToken(host);
477     std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
478     if (renderRemoteObj_ == nullptr) {
479         HILOG_WARN("renderRemoteObj is null,render service may exit already");
480         return;
481     }
482     renderRemoteObj_->CleanFormHost(host);
483 }
484 
AddRenderDeathRecipient(const sptr<IRemoteObject> & remoteObject)485 void FormRenderMgrInner::AddRenderDeathRecipient(const sptr<IRemoteObject> &remoteObject)
486 {
487     std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
488     if (renderRemoteObj_) {
489         HILOG_INFO("renderDeathRecipient is exist, no need to add again");
490         return;
491     }
492     guard.unlock();
493 
494     HILOG_INFO("Get renderRemoteObj,add death recipient");
495     auto renderRemoteObj = iface_cast<IFormRender>(remoteObject);
496     if (renderRemoteObj == nullptr) {
497         HILOG_ERROR("null renderRemoteObj");
498         return;
499     }
500 
501     if (renderDeathRecipient_ == nullptr) {
502         renderDeathRecipient_ = new (std::nothrow) FormRenderRecipient([this]() {
503             HILOG_WARN("FRS is Death, userId:%{public}d, isActiveUser:%{public}d", userId_, isActiveUser_);
504             if (isActiveUser_) {
505                 RerenderAllForms();
506             } else {
507                 std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
508                 renderRemoteObj_ = nullptr;
509                 guard.unlock();
510             }
511         });
512     }
513     if (!remoteObject->AddDeathRecipient(renderDeathRecipient_)) {
514         HILOG_ERROR("AddDeathRecipient failed");
515         return;
516     }
517     SetRenderRemoteObj(renderRemoteObj);
518 }
519 
ConnectRenderService(const sptr<FormRenderConnection> & connection,int32_t level) const520 inline ErrCode FormRenderMgrInner::ConnectRenderService(
521     const sptr<FormRenderConnection> &connection, int32_t level) const
522 {
523     if (connection == nullptr) {
524         HILOG_INFO("null connection");
525         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
526     }
527     Want want;
528     want.SetElementName(Constants::FRS_BUNDLE_NAME, "ServiceExtension");
529     want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
530     if (level > 0) {
531         want.SetParam(DLP_INDEX, Constants::DEFAULT_SANDBOX_FRS_APP_INDEX);
532         want.SetParam(Constants::FRS_APP_INDEX, Constants::DEFAULT_SANDBOX_FRS_APP_INDEX);
533     }
534     connection->SetStateConnecting();
535     return FormAmsHelper::GetInstance().ConnectServiceAbilityWithUserId(want, connection, GetUserId());
536 }
537 
SetUserId(int32_t userId)538 void FormRenderMgrInner::SetUserId(int32_t userId)
539 {
540     userId_ = userId;
541 }
542 
GetUserId() const543 int32_t FormRenderMgrInner::GetUserId() const
544 {
545     return userId_;
546 }
547 
RerenderAllFormsImmediate()548 void FormRenderMgrInner::RerenderAllFormsImmediate()
549 {
550     HILOG_INFO("Called");
551     isActiveUser_ = true;
552     if (etsHosts_.empty()) {
553         HILOG_WARN("All hosts died, no need to rerender.");
554         return;
555     }
556     NotifyHostRenderServiceIsDead();
557 }
558 
DisconnectAllRenderConnections()559 void FormRenderMgrInner::DisconnectAllRenderConnections()
560 {
561     HILOG_INFO("renderFormConnections size: %{public}zu.", renderFormConnections_.size());
562     std::lock_guard<std::mutex> lock(resourceMutex_);
563     size_t size = renderFormConnections_.size();
564     for (auto iter = renderFormConnections_.begin(); iter != renderFormConnections_.end();) {
565         DisconnectRenderService(iter->second, size);
566         iter = renderFormConnections_.erase(iter);
567         size--;
568     }
569     isActiveUser_ = false;
570 }
571 
DisconnectRenderService(const sptr<FormRenderConnection> connection,size_t size) const572 void FormRenderMgrInner::DisconnectRenderService(const sptr<FormRenderConnection> connection, size_t size) const
573 {
574     if (size == LAST_CONNECTION) {
575         HILOG_INFO("This is the last connection, disconnect render service delay");
576         FormAmsHelper::GetInstance().DisconnectServiceAbilityDelay(connection, FORM_DISCONNECT_FRS_DELAY_TIME);
577     } else {
578         HILOG_DEBUG("Disconnect render service ability");
579         FormAmsHelper::GetInstance().DisconnectServiceAbility(connection);
580     }
581 }
582 
OnRenderingBlock(const std::string & bundleName)583 void FormRenderMgrInner::OnRenderingBlock(const std::string &bundleName)
584 {
585     HILOG_INFO("bundleName:%{public}s", bundleName.c_str());
586     FormEventInfo eventInfo;
587     eventInfo.bundleName = bundleName;
588     FormEventReport::SendSecondFormEvent(
589         FormEventName::FORM_RENDER_BLOCK, HiSysEventType::FAULT, eventInfo);
590 
591     FormTrustMgr::GetInstance().MarkTrustFlag(bundleName, false);
592 
593     Want want;
594     want.SetElementName(Constants::FRS_BUNDLE_NAME, "ServiceExtension");
595     want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
596     FormAmsHelper::GetInstance().StopExtensionAbility(want);
597 }
598 
AddHostToken(const sptr<IRemoteObject> & host,int64_t formId)599 inline void FormRenderMgrInner::AddHostToken(const sptr<IRemoteObject> &host, int64_t formId)
600 {
601     std::lock_guard<std::mutex> lock(resourceMutex_);
602     auto iter = etsHosts_.find(host);
603     if (iter == etsHosts_.end()) {
604         HILOG_DEBUG("Add host, current etsHosts.size:%{public}zu", etsHosts_.size());
605         std::unordered_set<int64_t> formIdSet;
606         formIdSet.emplace(formId);
607         etsHosts_.emplace(host, formIdSet);
608     } else {
609         HILOG_DEBUG("Add formId to host, current etsHosts.size:%{public}zu", etsHosts_.size());
610         iter->second.emplace(formId);
611     }
612 }
613 
RemoveHostToken(const sptr<IRemoteObject> & host)614 void FormRenderMgrInner::RemoveHostToken(const sptr<IRemoteObject> &host)
615 {
616     size_t left = 0;
617     std::unordered_map<int64_t, sptr<FormRenderConnection>> connections;
618     {
619         std::lock_guard<std::mutex> lock(resourceMutex_);
620         auto iter = etsHosts_.find(host);
621         if (iter == etsHosts_.end()) {
622             HILOG_ERROR("Can't find host in etsHosts");
623             return;
624         }
625         auto formIdSet = iter->second;
626         etsHosts_.erase(host);
627         if (etsHosts_.empty()) {
628             HILOG_DEBUG("etsHosts is empty, disconnect all connections size:%{public}zu",
629                 renderFormConnections_.size());
630             connections.swap(renderFormConnections_);
631         } else {
632             for (const int64_t formId : formIdSet) {
633                 FormRecord formRecord;
634                 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
635                     connections.emplace(formId, renderFormConnections_[formId]);
636                     renderFormConnections_.erase(formId);
637                 }
638             }
639         }
640         left = renderFormConnections_.size();
641     }
642     for (auto iter = connections.begin(); iter != connections.end();) {
643         DisconnectRenderService(iter->second, connections.size() > left ? connections.size() : left);
644         iter = connections.erase(iter);
645     }
646 }
647 
NotifyHostRenderServiceIsDead() const648 void FormRenderMgrInner::NotifyHostRenderServiceIsDead() const
649 {
650     {
651         std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
652         if (renderRemoteObj_) {
653             HILOG_WARN("FRS is not died");
654             return;
655         }
656     }
657 
658     std::unordered_map<sptr<IRemoteObject>, std::unordered_set<int64_t>, RemoteObjHash> hostsForNotify;
659     {
660         std::lock_guard<std::mutex> lock(resourceMutex_);
661         HILOG_INFO("Notify hosts the render is dead, hosts.size:%{public}zu", etsHosts_.size());
662         auto tmpMap(etsHosts_);
663         hostsForNotify.swap(tmpMap);
664     }
665     for (const auto &item : hostsForNotify) {
666         sptr<IRemoteObject> hostClient = item.first;
667         if (hostClient == nullptr) {
668             HILOG_ERROR("null hostClient");
669             continue;
670         }
671         FormHostTaskMgr::GetInstance().PostFrsDiedTaskToHost(hostClient);
672     }
673 }
674 
GetRenderRemoteObj() const675 sptr<IFormRender> FormRenderMgrInner::GetRenderRemoteObj() const
676 {
677     return renderRemoteObj_;
678 }
679 
SetRenderRemoteObj(sptr<IFormRender> remoteObject)680 void FormRenderMgrInner::SetRenderRemoteObj(sptr<IFormRender> remoteObject)
681 {
682     std::unique_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
683     renderRemoteObj_ = remoteObject;
684 }
685 
GetReRenderCount() const686 int32_t FormRenderMgrInner::GetReRenderCount() const
687 {
688     return atomicRerenderCount_;
689 }
690 
RecycleForms(const std::vector<int64_t> & formIds,const Want & want,const sptr<IRemoteObject> & remoteObjectOfHost)691 ErrCode FormRenderMgrInner::RecycleForms(
692     const std::vector<int64_t> &formIds, const Want &want, const sptr<IRemoteObject> &remoteObjectOfHost)
693 {
694     HILOG_DEBUG("call");
695     RecoverFRSOnFormActivity();
696     sptr<IRemoteObject> remoteObject;
697     auto ret = GetRenderObject(remoteObject);
698     if (ret != ERR_OK) {
699         HILOG_ERROR("null remoteObjectGotten");
700         return ret;
701     }
702 
703     std::vector<int64_t> connectedForms;
704     GetConnectedForms(formIds, connectedForms);
705     FormStatusTaskMgr::GetInstance().PostRecycleForms(connectedForms, want, remoteObjectOfHost, remoteObject);
706     return ERR_OK;
707 }
708 
RecoverForms(const std::vector<int64_t> & formIds,const WantParams & wantParams)709 ErrCode FormRenderMgrInner::RecoverForms(const std::vector<int64_t> &formIds, const WantParams &wantParams)
710 {
711     HILOG_INFO("call");
712     RecoverFRSOnFormActivity();
713     sptr<IRemoteObject> remoteObject;
714     auto ret = GetRenderObject(remoteObject);
715     if (ret != ERR_OK) {
716         HILOG_ERROR("null remoteObjectGotten");
717         return ret;
718     }
719 
720     for (const int64_t &formId : formIds) {
721         Want want;
722         want.SetParams(wantParams);
723 
724         FormRecord formRecord;
725         if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
726             HILOG_ERROR("form record %{public}" PRId64 " not exist", formId);
727             continue;
728         }
729 
730         std::string cacheData;
731         std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap;
732         if (FormCacheMgr::GetInstance().GetData(formRecord.formId, cacheData, imageDataMap)) {
733             formRecord.formProviderInfo.SetImageDataMap(imageDataMap);
734         }
735 
736         std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
737         want.SetParam(Constants::FORM_SUPPLY_UID, uid);
738 
739         int32_t connectId = 0;
740         if (GetRenderFormConnectId(formId, connectId)) {
741             want.SetParam(Constants::FORM_CONNECT_ID, connectId);
742             std::string statusData;
743             if (FormInfoRdbStorageMgr::GetInstance().LoadStatusData(std::to_string(formId), statusData) != ERR_OK) {
744                 HILOG_ERROR("read status data of %{public}" PRId64 " failed.", formId);
745             }
746             want.SetParam(Constants::FORM_STATUS_DATA, statusData);
747 
748             FormStatusTaskMgr::GetInstance().PostRecoverForm(formRecord, want, remoteObject);
749         } else {
750             HILOG_ERROR("can't find connection of %{public}" PRId64, formId);
751         }
752     }
753     return ERR_OK;
754 }
755 
UpdateFormSize(const int64_t & formId,float width,float height,float borderWidth)756 ErrCode FormRenderMgrInner::UpdateFormSize(const int64_t &formId, float width, float height, float borderWidth)
757 {
758     HILOG_DEBUG("call");
759     RecoverFRSOnFormActivity();
760     sptr<IRemoteObject> remoteObject;
761     auto ret = GetRenderObject(remoteObject);
762     if (ret != ERR_OK) {
763         HILOG_ERROR("null remoteObjectGotten");
764         return ret;
765     }
766 
767     FormRecord formRecord;
768     if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
769         HILOG_ERROR("form record %{public}" PRId64 " not exist", formId);
770         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
771     }
772     std::string uid = std::to_string(formRecord.providerUserId) + formRecord.bundleName;
773     FormRenderTaskMgr::GetInstance().PostUpdateFormSize(formId, width, height, borderWidth, uid, remoteObject);
774     return ERR_OK;
775 }
776 
GetRenderObject(sptr<IRemoteObject> & renderObj)777 ErrCode FormRenderMgrInner::GetRenderObject(sptr<IRemoteObject> &renderObj)
778 {
779     std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
780     if (renderRemoteObj_ == nullptr) {
781         HILOG_ERROR("null renderRemoteObj");
782         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
783     }
784     renderObj = renderRemoteObj_->AsObject();
785     if (renderObj == nullptr) {
786         HILOG_ERROR("null remoteObj");
787         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
788     }
789     return ERR_OK;
790 }
791 
GetRenderFormConnectId(const int64_t formId,int32_t & connectId)792 bool FormRenderMgrInner::GetRenderFormConnectId(const int64_t formId, int32_t &connectId)
793 {
794     std::lock_guard<std::mutex> lock(resourceMutex_);
795     auto conIterator = renderFormConnections_.find(formId);
796     if (conIterator != renderFormConnections_.end()) {
797         auto connection = conIterator->second;
798         if (connection == nullptr) {
799             HILOG_ERROR("connection of %{public}" PRId64 " is null.", formId);
800             return false;
801         }
802         connectId = connection->GetConnectId();
803         return true;
804     }
805     HILOG_ERROR("Not find renderFormConnection. formId: %{public}" PRId64, formId);
806     return false;
807 }
808 
GetRenderFormConnection(sptr<FormRenderConnection> & connection,const int64_t formId)809 bool FormRenderMgrInner::GetRenderFormConnection(sptr<FormRenderConnection> &connection, const int64_t formId)
810 {
811     std::lock_guard<std::mutex> lock(resourceMutex_);
812     HILOG_DEBUG("renderFormConnections_ size:%{public}zu", renderFormConnections_.size());
813     auto conIterator = renderFormConnections_.find(formId);
814     if (conIterator != renderFormConnections_.end()) {
815         connection = conIterator->second;
816         return true;
817     }
818     return false;
819 }
820 
GetConnectedForms(const std::vector<int64_t> & formIds,std::vector<int64_t> & connectedForms)821 void FormRenderMgrInner::GetConnectedForms(const std::vector<int64_t> &formIds, std::vector<int64_t> &connectedForms)
822 {
823     std::lock_guard<std::mutex> lock(resourceMutex_);
824     for (const int64_t &formId : formIds) {
825         auto conIterator = renderFormConnections_.find(formId);
826         if (conIterator != renderFormConnections_.end()) {
827             auto connection = conIterator->second;
828             if (connection == nullptr) {
829                 HILOG_ERROR("connection of %{public}" PRId64 " is null.", formId);
830                 continue;
831             }
832             connectedForms.emplace_back(formId);
833         } else {
834             HILOG_ERROR("can't find connection of %{public}" PRId64, formId);
835         }
836     }
837 }
838 
RenderConnectedForm(const FormRecord & formRecord,Want & want,const sptr<FormRenderConnection> & connection)839 ErrCode FormRenderMgrInner::RenderConnectedForm(
840     const FormRecord &formRecord, Want &want, const sptr<FormRenderConnection> &connection)
841 {
842     if (connection == nullptr) {
843         HILOG_ERROR("null connection");
844         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
845     }
846 
847     RecoverFRSOnFormActivity();
848     std::shared_lock<std::shared_mutex> guard(renderRemoteObjMutex_);
849     if (renderRemoteObj_ == nullptr) {
850         connection->UpdateFormRecord(formRecord);
851         connection->UpdateWantParams(want.GetParams());
852         ErrCode ret = ConnectRenderService(connection, formRecord.privacyLevel);
853         HILOG_INFO("ret:%{public}d", ret);
854         if (ret) {
855             FormRenderMgr::GetInstance().HandleConnectFailed(formRecord.formId, ret);
856         }
857         return ret;
858     }
859     auto remoteObject = renderRemoteObj_->AsObject();
860     if (remoteObject == nullptr) {
861         HILOG_ERROR("null remoteObject");
862         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
863     }
864     guard.unlock();
865     want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
866     FormStatusTaskMgr::GetInstance().PostRenderForm(formRecord, want, remoteObject);
867     return ERR_OK;
868 }
869 
PostStopRenderingFormTask(const FormRecord & formRecord,Want & want)870 ErrCode FormRenderMgrInner::PostStopRenderingFormTask(const FormRecord &formRecord, Want &want)
871 {
872     std::lock_guard<std::mutex> lock(resourceMutex_);
873     auto conIterator = renderFormConnections_.find(formRecord.formId);
874     if (conIterator != renderFormConnections_.end()) {
875         auto connection = conIterator->second;
876         if (connection == nullptr) {
877             HILOG_ERROR("null connection");
878             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
879         }
880         sptr<IRemoteObject> remoteObject;
881         auto ret = GetRenderObject(remoteObject);
882         if (ret != ERR_OK) {
883             HILOG_ERROR("null remoteObjectGotten");
884             return ret;
885         }
886         want.SetParam(Constants::FORM_CONNECT_ID, connection->GetConnectId());
887         FormStatusTaskMgr::GetInstance().PostStopRenderingForm(formRecord, std::move(want), remoteObject);
888         return ERR_OK;
889     }
890     return ERR_APPEXECFWK_FORM_INVALID_PARAM;
891 }
892 
CheckRenderConnectionExistById(int64_t formId)893 ErrCode FormRenderMgrInner::CheckRenderConnectionExistById(int64_t formId)
894 {
895     std::lock_guard<std::mutex> lock(resourceMutex_);
896     auto conIterator = renderFormConnections_.find(formId);
897     if (conIterator != renderFormConnections_.end()) {
898         auto connection = conIterator->second;
899         if (connection == nullptr) {
900             HILOG_ERROR("null connection");
901             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
902         }
903         return ERR_OK;
904     }
905     return ERR_APPEXECFWK_FORM_INVALID_PARAM;
906 }
907 
RecoverFRSOnFormActivity()908 void FormRenderMgrInner::RecoverFRSOnFormActivity()
909 {
910     if (isFrsDiedInLowMemory_.exchange(false)) {
911         NotifyHostRenderServiceIsDead();
912     }
913 }
914 
GetIsFRSDiedInLowMemory()915 bool FormRenderMgrInner::GetIsFRSDiedInLowMemory()
916 {
917     HILOG_INFO("call isFrsDiedInLowMemory_ %{public}d", isFrsDiedInLowMemory_.load());
918     return isFrsDiedInLowMemory_;
919 }
920 
OnRemoteDied(const wptr<IRemoteObject> & remote)921 void FormRenderRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
922 {
923     HILOG_INFO("Recv FormRenderService death notice");
924     if (handler_) {
925         handler_();
926     }
927 }
928 
FormRenderRecipient(RemoteDiedHandler handler)929 FormRenderRecipient::FormRenderRecipient(RemoteDiedHandler handler) : handler_(handler) {}
930 
~FormRenderRecipient()931 FormRenderRecipient::~FormRenderRecipient() {}
932 } // namespace AppExecFwk
933 } // namespace OHOS
934