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