1 /*
2 * Copyright (c) 2021-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 "data_center/form_info/form_info_mgr.h"
17
18 #include "bundle_mgr_client.h"
19 #include "extension_form_profile.h"
20 #include "fms_log_wrapper.h"
21 #include "bms_mgr/form_bms_helper.h"
22 #include "data_center/database/form_db_cache.h"
23 #include "data_center/form_info/form_info_storage.h"
24 #include "data_center/form_info/form_info_rdb_storage_mgr.h"
25 #include "form_mgr_errors.h"
26 #include "common/util/form_util.h"
27 #include "hitrace_meter.h"
28 #include "in_process_call_wrapper.h"
29 #include "ipc_skeleton.h"
30 #include "json_serializer.h"
31 #include "permission_verification.h"
32 #include "common/event/form_event_report.h"
33 #include "common_event.h"
34 #include "common_event_manager.h"
35 #include "feature/bundle_distributed/form_distributed_mgr.h"
36
37 namespace OHOS {
38 namespace AppExecFwk {
39 namespace {
40 const std::string FORM_METADATA_NAME = "ohos.extension.form";
41 const std::uint32_t ERR_VERSION_CODE = 0;
42 const std::string FMS_IS_READY_EVENT = "fmsIsReady";
43 const std::string PERMISSION_REQUIRE_FORM = "ohos.permission.REQUIRE_FORM";
44 constexpr int DISTRIBUTED_BUNDLE_MODULE_LENGTH = 2;
45 } // namespace
46
LoadFormConfigInfoByBundleName(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)47 ErrCode FormInfoHelper::LoadFormConfigInfoByBundleName(const std::string &bundleName, std::vector<FormInfo> &formInfos,
48 int32_t userId)
49 {
50 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
51 if (bundleName.empty()) {
52 HILOG_ERROR("invalid bundleName");
53 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
54 }
55
56 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
57 if (iBundleMgr == nullptr) {
58 HILOG_ERROR("get IBundleMgr failed");
59 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
60 }
61
62 BundleInfo bundleInfo;
63 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
64 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(bundleName, flag, bundleInfo, userId))) {
65 HILOG_ERROR("get bundleInfo failed");
66 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
67 }
68 if (bundleInfo.abilityInfos.empty()) {
69 HILOG_WARN("empty abilityInfos");
70 // Check if current bundle contains FA forms.
71 LoadAbilityFormConfigInfo(bundleInfo, formInfos);
72 // Check if current bundle contains Stage forms.
73 LoadStageFormConfigInfo(bundleInfo, formInfos, userId);
74 return ERR_OK;
75 }
76 if (bundleInfo.abilityInfos[0].isStageBasedModel) {
77 LoadStageFormConfigInfo(bundleInfo, formInfos, userId);
78 } else {
79 LoadAbilityFormConfigInfo(bundleInfo, formInfos);
80 }
81 return ERR_OK;
82 }
83
LoadStageFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos,int32_t userId)84 ErrCode FormInfoHelper::LoadStageFormConfigInfo(
85 const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos, int32_t userId)
86 {
87 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
88 std::shared_ptr<BundleMgrClient> client = DelayedSingleton<BundleMgrClient>::GetInstance();
89 if (client == nullptr) {
90 HILOG_ERROR("fail get BundleMgrClient");
91 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
92 }
93 for (auto const &extensionInfo: bundleInfo.extensionInfos) {
94 if (extensionInfo.type != ExtensionAbilityType::FORM) {
95 continue;
96 }
97 HapModuleInfo sharedModule;
98 bool hasDistributedForm = LoadSharedModuleInfo(bundleInfo, sharedModule);
99 DistributedModule distributedModule;
100 distributedModule.userId = userId;
101 distributedModule.entryModule = bundleInfo.entryModuleName;
102 distributedModule.uiModule = sharedModule.moduleName;
103 FormDistributedMgr::GetInstance().SetBundleDistributedStatus(
104 bundleInfo.name, hasDistributedForm, distributedModule);
105 std::vector<std::string> profileInfos {};
106 if (hasDistributedForm) {
107 if (!client->GetProfileFromSharedHap(sharedModule, extensionInfo, profileInfos)) {
108 HILOG_WARN("fail get profile info from shared hap");
109 continue;
110 }
111 } else if (!client->GetResConfigFile(extensionInfo, FORM_METADATA_NAME, profileInfos)) {
112 HILOG_ERROR("fail get form metadata");
113 continue;
114 }
115 for (const auto &profileInfo: profileInfos) {
116 std::vector<ExtensionFormInfo> extensionFormInfos;
117 int32_t privacyLevel = 0;
118 ErrCode errCode = ExtensionFormProfile::TransformTo(profileInfo, extensionFormInfos, privacyLevel);
119 if (errCode != ERR_OK) {
120 HILOG_WARN("fail transform profile to extension form info");
121 continue;
122 }
123 for (const auto &extensionFormInfo: extensionFormInfos) {
124 FormInfo formInfo(extensionInfo, extensionFormInfo);
125 if (!bundleInfo.applicationInfo.isSystemApp) {
126 formInfo.transparencyEnabled = false;
127 }
128 if (hasDistributedForm) {
129 formInfo.package = extensionInfo.bundleName + sharedModule.moduleName;
130 }
131 formInfo.versionCode = bundleInfo.versionCode;
132 formInfo.bundleType = bundleInfo.applicationInfo.bundleType;
133 formInfo.privacyLevel = privacyLevel;
134 HILOG_INFO("LoadStageFormConfigInfo, bundleName:%{public}s, name:%{public}s, renderingMode:%{public}d, "
135 "moduleName:%{public}s, hasDistributedForm:%{public}d",
136 formInfo.bundleName.c_str(), formInfo.name.c_str(), static_cast<int>(formInfo.renderingMode),
137 formInfo.moduleName.c_str(), hasDistributedForm);
138 NewFormEventInfo eventInfo;
139 eventInfo.bundleName = formInfo.bundleName;
140 eventInfo.formName = formInfo.name;
141 eventInfo.renderingMode = static_cast<int32_t>(formInfo.renderingMode);
142 FormEventReport::SendLoadStageFormConfigInfoEvent(FormEventName::LOAD_STAGE_FORM_CONFIG_INFO,
143 HiSysEventType::BEHAVIOR, eventInfo);
144 formInfos.emplace_back(formInfo);
145 }
146 }
147 }
148 return ERR_OK;
149 }
150
LoadAbilityFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)151 ErrCode FormInfoHelper::LoadAbilityFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
152 {
153 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
154 if (iBundleMgr == nullptr) {
155 HILOG_ERROR("get IBundleMgr failed");
156 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
157 }
158 const std::string &bundleName = bundleInfo.name;
159 for (const auto &moduleInfo: bundleInfo.hapModuleInfos) {
160 const std::string &moduleName = moduleInfo.moduleName;
161 std::vector<FormInfo> formInfoVec {};
162 if (!IN_PROCESS_CALL(iBundleMgr->GetFormsInfoByModule(bundleName, moduleName, formInfoVec))) {
163 continue;
164 }
165 for (auto &formInfo: formInfoVec) {
166 formInfo.versionCode = bundleInfo.versionCode;
167 formInfo.bundleType = bundleInfo.applicationInfo.bundleType;
168 formInfos.emplace_back(formInfo);
169 }
170 }
171 return ERR_OK;
172 }
GetResourceManager(const BundleInfo & bundleInfo)173 std::shared_ptr<Global::Resource::ResourceManager> FormInfoHelper::GetResourceManager(const BundleInfo &bundleInfo)
174 {
175 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
176 HILOG_INFO("bundleInfoName:%{public}s", bundleInfo.name.c_str());
177 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
178 if (resourceManager == nullptr) {
179 HILOG_ERROR("InitResourceManager failed");
180 return nullptr;
181 }
182 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
183 std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
184 if (!moduleResPath.empty()) {
185 HILOG_DEBUG("DistributedBms::InitResourceManager, moduleResPath: %{private}s", moduleResPath.c_str());
186 if (!resourceManager->AddResource(moduleResPath.c_str())) {
187 HILOG_ERROR("DistributedBms::InitResourceManager AddResource failed");
188 }
189 }
190 }
191 return resourceManager;
192 }
193
GetFormInfoDisplayName(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,FormInfo & formInfo)194 ErrCode FormInfoHelper::GetFormInfoDisplayName(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager,
195 FormInfo &formInfo)
196 {
197 if (formInfo.displayNameId != 0) {
198 std::string displayName;
199 auto state = resourceManager->GetStringById(static_cast<uint32_t>(formInfo.displayNameId), displayName);
200 if (state != OHOS::Global::Resource::RState::SUCCESS) {
201 HILOG_ERROR("ResourceManager GetStringById with displayNameId failed");
202 return ERR_APPEXECFWK_FORM_COMMON_CODE;
203 }
204 formInfo.displayName = displayName;
205 }
206 return ERR_OK;
207 }
208
GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,FormInfo & formInfo)209 ErrCode FormInfoHelper::GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager,
210 FormInfo &formInfo)
211 {
212 if (formInfo.descriptionId != 0) {
213 std::string description;
214 auto state = resourceManager->GetStringById(static_cast<uint32_t>(formInfo.descriptionId), description);
215 if (state != OHOS::Global::Resource::RState::SUCCESS) {
216 HILOG_ERROR("ResourceManager GetStringById failed");
217 return ERR_APPEXECFWK_FORM_COMMON_CODE;
218 }
219 formInfo.description = description;
220 }
221 return ERR_OK;
222 }
223
BundleFormInfo(const std::string & bundleName)224 BundleFormInfo::BundleFormInfo(const std::string &bundleName) : bundleName_(bundleName)
225 {
226 }
227
InitFromJson(const std::string & formInfoStoragesJson)228 ErrCode BundleFormInfo::InitFromJson(const std::string &formInfoStoragesJson)
229 {
230 nlohmann::json jsonObject = nlohmann::json::parse(formInfoStoragesJson, nullptr, false);
231 if (jsonObject.is_discarded() || !jsonObject.is_array()) {
232 HILOG_ERROR("bad profile");
233 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
234 }
235 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
236 auto formInfoStorages = jsonObject.get<std::vector<AAFwk::FormInfoStorage>>();
237 for (const auto &item : formInfoStorages) {
238 formInfoStorages_.push_back(item);
239 }
240 return ERR_OK;
241 }
242
UpdateStaticFormInfos(int32_t userId)243 ErrCode BundleFormInfo::UpdateStaticFormInfos(int32_t userId)
244 {
245 HILOG_DEBUG("Update static form infos, userId is %{public}d", userId);
246 std::vector<FormInfo> formInfos;
247 ErrCode errCode = FormInfoHelper::LoadFormConfigInfoByBundleName(bundleName_, formInfos, userId);
248 if (errCode != ERR_OK) {
249 HILOG_ERROR("LoadFormConfigInfoByBundleName failed, errCode:%{public}d", errCode);
250 return errCode;
251 }
252
253 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
254 if (!formInfos.empty()) {
255 std::vector<FormDBInfo> formDBInfos;
256 std::vector<FormInfo> finalFormInfos;
257 FormDbCache::GetInstance().GetAllFormDBInfoByBundleName(bundleName_, userId, formDBInfos);
258 HandleFormInfosMaxLimit(formInfos, finalFormInfos, formDBInfos);
259 bool findUser = false;
260 for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end(); ++item) {
261 // Update all user's formInfos
262 HILOG_DEBUG("Update formInfos, user:%{public}d", item->userId);
263 item->formInfos = finalFormInfos;
264 findUser = findUser || (item->userId == userId);
265 }
266 if (!findUser) {
267 HILOG_DEBUG("Add new userId, user:%{public}d", userId);
268 formInfoStorages_.emplace_back(userId, finalFormInfos);
269 }
270 return UpdateFormInfoStorageLocked();
271 }
272
273 bool IsBundleDistributed = FormDistributedMgr::GetInstance().IsBundleDistributed(bundleName_, userId);
274 HILOG_INFO("The new package of %{public}s does not contain a card, IsBundleDistributed:%{public}d.",
275 bundleName_.c_str(), IsBundleDistributed);
276 if (IsBundleDistributed) {
277 ClearDistributedFormInfos(userId);
278 } else {
279 HILOG_INFO("clear normal app formInfos, bundleName: %{public}s", bundleName_.c_str());
280 formInfoStorages_.clear();
281 }
282 return UpdateFormInfoStorageLocked();
283 }
284
LoadSharedModuleInfo(const BundleInfo & bundleInfo,HapModuleInfo & shared)285 bool FormInfoHelper::LoadSharedModuleInfo(const BundleInfo &bundleInfo, HapModuleInfo &shared)
286 {
287 auto hapModuleInfoBegin = bundleInfo.hapModuleInfos.begin();
288 auto hapModuleInfoEnd = bundleInfo.hapModuleInfos.end();
289 auto entryIt = std::find_if(hapModuleInfoBegin, hapModuleInfoEnd, [](const auto &hapInfo) {
290 return (hapInfo.moduleType == ModuleType::ENTRY) && (!hapInfo.formWidgetModule.empty());
291 });
292
293 if (entryIt == hapModuleInfoEnd) {
294 return false;
295 }
296
297 if (bundleInfo.hapModuleInfos.size() < DISTRIBUTED_BUNDLE_MODULE_LENGTH) {
298 // Install distributed hap package
299 return true;
300 }
301
302 auto sharedIt = std::find_if(hapModuleInfoBegin, hapModuleInfoEnd, [entryIt](const auto &hapInfo) {
303 return (hapInfo.moduleType == ModuleType::SHARED) && (!hapInfo.formExtensionModule.empty()) &&
304 ((entryIt->name == hapInfo.formExtensionModule) && (entryIt->formWidgetModule == hapInfo.name));
305 });
306 if (sharedIt == hapModuleInfoEnd) {
307 return false;
308 }
309 shared = *sharedIt;
310 return true;
311 }
312
Remove(int32_t userId)313 ErrCode BundleFormInfo::Remove(int32_t userId)
314 {
315 HILOG_INFO("userId is %{public}d", userId);
316 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
317 for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
318 if (item->userId == userId) {
319 item = formInfoStorages_.erase(item);
320 } else {
321 ++item;
322 }
323 }
324 return UpdateFormInfoStorageLocked();
325 }
326
AddDynamicFormInfo(const FormInfo & formInfo,int32_t userId)327 ErrCode BundleFormInfo::AddDynamicFormInfo(const FormInfo &formInfo, int32_t userId)
328 {
329 HILOG_INFO("userId is %{public}d", userId);
330 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
331 for (auto &formInfoStorage : formInfoStorages_) {
332 if (formInfoStorage.userId != userId) {
333 continue;
334 }
335 bool isSame = false;
336 for (const auto &item : formInfoStorage.formInfos) {
337 if (item.name == formInfo.name && item.moduleName == formInfo.moduleName) {
338 isSame = true;
339 break;
340 }
341 }
342
343 if (isSame) {
344 HILOG_ERROR("The same form already exists");
345 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
346 }
347 formInfoStorage.formInfos.push_back(formInfo);
348 return UpdateFormInfoStorageLocked();
349 }
350 // no match user id
351 std::vector<FormInfo> formInfos;
352 formInfos.push_back(formInfo);
353 formInfoStorages_.emplace_back(userId, formInfos);
354 return UpdateFormInfoStorageLocked();
355 }
356
RemoveDynamicFormInfo(const std::string & moduleName,const std::string & formName,int32_t userId)357 ErrCode BundleFormInfo::RemoveDynamicFormInfo(const std::string &moduleName, const std::string &formName,
358 int32_t userId)
359 {
360 HILOG_INFO("userId is %{public}d", userId);
361 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
362 for (auto &formInfoStorage : formInfoStorages_) {
363 if (formInfoStorage.userId != userId) {
364 continue;
365 }
366 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
367 if (item->name != formName || item->moduleName != moduleName) {
368 ++item;
369 continue;
370 }
371 // form found
372 if (item->isStatic) {
373 HILOG_ERROR("the specifiedFormInfo is static,can't be removed");
374 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
375 }
376 item = formInfoStorage.formInfos.erase(item);
377 return UpdateFormInfoStorageLocked();
378 }
379 }
380 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
381 }
382
RemoveAllDynamicFormsInfo(int32_t userId)383 ErrCode BundleFormInfo::RemoveAllDynamicFormsInfo(int32_t userId)
384 {
385 HILOG_INFO("userId is %{public}d", userId);
386 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
387 int32_t numRemoved = 0;
388 for (auto &formInfoStorage : formInfoStorages_) {
389 if (formInfoStorage.userId != userId) {
390 continue;
391 }
392 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
393 if (!item->isStatic) {
394 ++numRemoved;
395 item = formInfoStorage.formInfos.erase(item);
396 } else {
397 ++item;
398 }
399 }
400 break;
401 }
402 if (numRemoved > 0) {
403 HILOG_ERROR("%{public}d dynamic forms info removed.", numRemoved);
404 return UpdateFormInfoStorageLocked();
405 }
406 return ERR_OK;
407 }
408
Empty() const409 bool BundleFormInfo::Empty() const
410 {
411 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
412 return formInfoStorages_.empty();
413 }
414
GetAllFormsInfo(std::vector<FormInfo> & formInfos,int32_t userId)415 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos, int32_t userId)
416 {
417 HILOG_DEBUG("begin");
418 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
419 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
420 for (const auto &item : formInfoStorages_) {
421 item.GetAllFormsInfo(userId, formInfos);
422 }
423 return ERR_OK;
424 }
425
GetVersionCode(int32_t userId)426 uint32_t BundleFormInfo::GetVersionCode(int32_t userId)
427 {
428 HILOG_DEBUG("begin");
429 std::vector<FormInfo> formInfos;
430 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
431 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
432 for (const auto &item : formInfoStorages_) {
433 item.GetAllFormsInfo(userId, formInfos);
434 for (const auto &info : formInfos) {
435 if (info.versionCode != ERR_VERSION_CODE) {
436 return info.versionCode;
437 }
438 }
439 }
440 return ERR_VERSION_CODE;
441 }
442
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)443 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos,
444 int32_t userId)
445 {
446 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
447 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
448 for (const auto &item : formInfoStorages_) {
449 item.GetFormsInfoByModule(userId, moduleName, formInfos);
450 }
451 return ERR_OK;
452 }
453
GetFormsInfoByFilter(const FormInfoFilter & filter,std::vector<FormInfo> & formInfos,int32_t userId)454 ErrCode BundleFormInfo::GetFormsInfoByFilter(
455 const FormInfoFilter &filter, std::vector<FormInfo> &formInfos, int32_t userId)
456 {
457 HILOG_DEBUG("begin");
458 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
459 auto newUserId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
460
461 for (const auto &item : formInfoStorages_) {
462 item.GetFormsInfoByFilter(newUserId, filter, formInfos);
463 }
464 return ERR_OK;
465 }
466
UpdateFormInfoStorageLocked()467 ErrCode BundleFormInfo::UpdateFormInfoStorageLocked()
468 {
469 ErrCode errCode;
470 if (formInfoStorages_.empty()) {
471 errCode = FormInfoRdbStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
472 } else {
473 nlohmann::json jsonObject = formInfoStorages_;
474 if (jsonObject.is_discarded()) {
475 HILOG_ERROR("bad form infos");
476 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
477 }
478 std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
479 errCode = FormInfoRdbStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
480 }
481 return errCode;
482 }
483
HandleFormInfosMaxLimit(std::vector<FormInfo> & inFormInfos,std::vector<FormInfo> & outFormInfos,const std::vector<FormDBInfo> & formDBInfos)484 void BundleFormInfo::HandleFormInfosMaxLimit(std::vector<FormInfo> &inFormInfos,
485 std::vector<FormInfo> &outFormInfos, const std::vector<FormDBInfo> &formDBInfos)
486 {
487 HILOG_INFO("formInfo num: %{public}zu,formDBInfo num: %{public}zu", inFormInfos.size(), formDBInfos.size());
488 std::set<std::string> formDBNames;
489 GetAllUsedFormName(formDBInfos, inFormInfos, formDBNames);
490 if (formDBNames.empty() || inFormInfos.size() <= Constants::FORM_INFO_MAX_NUM) {
491 if (inFormInfos.size() > Constants::FORM_INFO_MAX_NUM) {
492 unsigned int needPopNum = inFormInfos.size() - Constants::FORM_INFO_MAX_NUM;
493 for (unsigned int i = 0; i < needPopNum; i++) {
494 inFormInfos.pop_back();
495 }
496 }
497 outFormInfos = inFormInfos;
498 return;
499 }
500 int32_t addFormNum = 0;
501 unsigned int formNum = formDBNames.size();
502 if (formDBNames.size() < Constants::FORM_INFO_MAX_NUM) {
503 addFormNum = Constants::FORM_INFO_MAX_NUM - static_cast<int32_t>(formDBNames.size());
504 formNum = Constants::FORM_INFO_MAX_NUM;
505 }
506 for (auto formInfo : inFormInfos) {
507 bool isUsed = formDBNames.find(formInfo.name) != formDBNames.end();
508 if (isUsed) {
509 outFormInfos.push_back(formInfo);
510 } else if (!isUsed && addFormNum > 0) {
511 outFormInfos.push_back(formInfo);
512 addFormNum--;
513 }
514 if (outFormInfos.size() == formNum) {
515 break;
516 }
517 }
518 }
519
GetAllUsedFormName(const std::vector<FormDBInfo> & formDBInfos,const std::vector<FormInfo> & formInfos,std::set<std::string> & formDBNames)520 void BundleFormInfo::GetAllUsedFormName(const std::vector<FormDBInfo> &formDBInfos,
521 const std::vector<FormInfo> &formInfos, std::set<std::string> &formDBNames)
522 {
523 if (formDBInfos.empty() || formInfos.empty()) {
524 return;
525 }
526 for (auto formDBInfo : formDBInfos) {
527 if (formDBNames.count(formDBInfo.formName) > 0) {
528 continue;
529 }
530 for (auto formInfo : formInfos) {
531 if (formInfo.name == formDBInfo.formName) {
532 formDBNames.insert(formDBInfo.formName);
533 break;
534 }
535 }
536 }
537 HILOG_INFO("used form num: %{public}zu", formDBNames.size());
538 }
539
ClearDistributedFormInfos(int32_t userId)540 void BundleFormInfo::ClearDistributedFormInfos(int32_t userId)
541 {
542 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
543 if (iBundleMgr == nullptr) {
544 HILOG_ERROR("get IBundleMgr failed");
545 return;
546 }
547
548 BundleInfo bundleInfo;
549 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
550 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(bundleName_, flag, bundleInfo, userId))) {
551 HILOG_ERROR("get bundleInfo failed");
552 return;
553 }
554
555 if (bundleInfo.hapModuleInfos.size() < DISTRIBUTED_BUNDLE_MODULE_LENGTH) {
556 // install a part of distributed app package, do not clear for now
557 return;
558 }
559 HILOG_INFO("clear distributed app formInfos, bundleName: %{public}s", bundleName_.c_str());
560 formInfoStorages_.clear();
561 }
562
FormInfoMgr()563 FormInfoMgr::FormInfoMgr()
564 {
565 HILOG_INFO("create");
566 }
567
568 FormInfoMgr::~FormInfoMgr() = default;
569
Start()570 ErrCode FormInfoMgr::Start()
571 {
572 std::vector<std::pair<std::string, std::string>> formInfoStorages;
573 ErrCode errCode = FormInfoRdbStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
574 if (errCode != ERR_OK) {
575 HILOG_ERROR("LoadFormInfos failed");
576 return errCode;
577 }
578
579 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
580 for (const auto &item: formInfoStorages) {
581 const std::string &bundleName = item.first;
582 const std::string &formInfoStoragesJson = item.second;
583 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
584 errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
585 if (errCode != ERR_OK) {
586 continue;
587 }
588 HILOG_INFO("load bundle %{public}s form infos success.", bundleName.c_str());
589 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
590 }
591 HILOG_INFO("load bundle form infos from db done");
592 return ERR_OK;
593 }
594
UpdateStaticFormInfos(const std::string & bundleName,int32_t userId)595 ErrCode FormInfoMgr::UpdateStaticFormInfos(const std::string &bundleName, int32_t userId)
596 {
597 if (bundleName.empty()) {
598 HILOG_ERROR("empty bundleName");
599 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
600 }
601
602 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
603 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
604 auto search = bundleFormInfoMap_.find(bundleName);
605 if (search != bundleFormInfoMap_.end()) {
606 bundleFormInfoPtr = search->second;
607 } else {
608 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
609 }
610
611 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
612 if (errCode != ERR_OK) {
613 HILOG_ERROR("UpdateStaticFormInfos failed!");
614 return errCode;
615 }
616
617 if (bundleFormInfoPtr->Empty()) {
618 // no forms found, no need to be inserted into the map
619 return ERR_OK;
620 }
621
622 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
623 HILOG_INFO("success, bundleName=%{public}s", bundleName.c_str());
624 return ERR_OK;
625 }
626
Remove(const std::string & bundleName,int32_t userId)627 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
628 {
629 if (bundleName.empty()) {
630 HILOG_ERROR("empty bundleName");
631 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
632 }
633
634 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
635 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
636 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
637 // BundleFormInfo not found, no need to remove
638 return ERR_OK;
639 }
640
641 ErrCode errCode = ERR_OK;
642 if (bundleFormInfoIter->second != nullptr) {
643 errCode = bundleFormInfoIter->second->Remove(userId);
644 }
645
646 if (bundleFormInfoIter->second && bundleFormInfoIter->second->Empty()) {
647 bundleFormInfoMap_.erase(bundleFormInfoIter);
648 }
649 HILOG_INFO("success, bundleName=%{public}s", bundleName.c_str());
650 return errCode;
651 }
652
GetAllFormsInfo(std::vector<FormInfo> & formInfos,int32_t userId)653 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos, int32_t userId)
654 {
655 if (!CheckBundlePermission()) {
656 HILOG_ERROR("CheckBundlePermission is failed");
657 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
658 }
659 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
660 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
661 if (bundleFormInfo.second != nullptr) {
662 bundleFormInfo.second->GetAllFormsInfo(formInfos, userId);
663 }
664 }
665 return ERR_OK;
666 }
667
GetFormsInfoByFilter(const FormInfoFilter & filter,std::vector<FormInfo> & formInfos,int32_t userId)668 ErrCode FormInfoMgr::GetFormsInfoByFilter(
669 const FormInfoFilter &filter, std::vector<FormInfo> &formInfos, int32_t userId)
670 {
671 if (!CheckBundlePermission()) {
672 if (filter.bundleName.empty() || !IsCaller(filter.bundleName)) {
673 HILOG_ERROR("Permission is wrong");
674 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
675 }
676 }
677 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
678 if (filter.bundleName.empty()) {
679 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
680 if (bundleFormInfo.second != nullptr) {
681 bundleFormInfo.second->GetFormsInfoByFilter(filter, formInfos, userId);
682 }
683 }
684 } else {
685 auto bundleFormInfoIter = bundleFormInfoMap_.find(filter.bundleName);
686 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
687 HILOG_WARN("no forms found for bundle name:%{public}s", filter.bundleName.c_str());
688 return ERR_OK;
689 }
690 if (bundleFormInfoIter->second != nullptr) {
691 bundleFormInfoIter->second->GetFormsInfoByFilter(filter, formInfos, userId);
692 }
693 }
694 return ERR_OK;
695 }
696
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)697 ErrCode FormInfoMgr::GetFormsInfoByBundle(
698 const std::string &bundleName, std::vector<FormInfo> &formInfos, int32_t userId)
699 {
700 if (bundleName.empty()) {
701 HILOG_ERROR("empty bundleName");
702 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
703 }
704
705 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
706 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
707 }
708
709 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
710 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
711 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
712 HILOG_ERROR("no forms found");
713 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
714 }
715
716 if (bundleFormInfoIter->second != nullptr) {
717 bundleFormInfoIter->second->GetAllFormsInfo(formInfos, userId);
718 }
719 return ERR_OK;
720 }
721
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)722 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
723 std::vector<FormInfo> &formInfos, int32_t userId)
724 {
725 if (bundleName.empty()) {
726 HILOG_ERROR("empty bundleName");
727 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
728 }
729
730 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
731 HILOG_ERROR("CheckBundlePermission and IsCaller failed");
732 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
733 }
734
735 return GetFormsInfoByModuleWithoutCheck(bundleName, moduleName, formInfos, userId);
736 }
737
GetFormsInfoByModuleWithoutCheck(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)738 ErrCode FormInfoMgr::GetFormsInfoByModuleWithoutCheck(const std::string &bundleName, const std::string &moduleName,
739 std::vector<FormInfo> &formInfos, int32_t userId)
740 {
741 if (bundleName.empty()) {
742 HILOG_ERROR("empty bundleName");
743 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
744 }
745
746 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
747 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
748 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
749 HILOG_ERROR("no forms found for %{public}s", bundleName.c_str());
750 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
751 }
752
753 if (bundleFormInfoIter->second != nullptr) {
754 bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos, userId);
755 }
756 return ERR_OK;
757 }
758
GetFormsInfoByRecord(const FormRecord & formRecord,FormInfo & formInfo)759 ErrCode FormInfoMgr::GetFormsInfoByRecord(const FormRecord &formRecord, FormInfo &formInfo)
760 {
761 std::vector<FormInfo> formInfos;
762 {
763 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
764 auto bundleFormInfoIter = bundleFormInfoMap_.find(formRecord.bundleName);
765 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
766 HILOG_ERROR("no forms found for %{public}s", formRecord.bundleName.c_str());
767 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
768 }
769
770 if (bundleFormInfoIter->second == nullptr) {
771 HILOG_ERROR("null BundleFormInfo");
772 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
773 }
774
775 bundleFormInfoIter->second->GetFormsInfoByModule(formRecord.moduleName, formInfos);
776 }
777 for (const FormInfo &info : formInfos) {
778 if (info.name == formRecord.formName) {
779 formInfo = info;
780 break;
781 }
782 }
783 return formInfo.name.empty() ? ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED : ERR_OK;
784 }
785
CheckDynamicFormInfo(FormInfo & formInfo,const BundleInfo & bundleInfo)786 ErrCode FormInfoMgr::CheckDynamicFormInfo(FormInfo &formInfo, const BundleInfo &bundleInfo)
787 {
788 for (auto &moduleInfo : bundleInfo.hapModuleInfos) {
789 if (formInfo.moduleName != moduleInfo.moduleName) {
790 continue;
791 }
792 for (auto &abilityInfo : moduleInfo.abilityInfos) {
793 if (formInfo.abilityName != abilityInfo.name) {
794 continue;
795 }
796 formInfo.src = "";
797 return ERR_OK;
798 }
799 for (auto &extensionInfos : moduleInfo.extensionInfos) {
800 if (formInfo.abilityName != extensionInfos.name) {
801 continue;
802 }
803 formInfo.src = "./js/" + formInfo.name + "/pages/index/index";
804 return ERR_OK;
805 }
806 HILOG_ERROR("No match abilityName found");
807 return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY;
808 }
809
810 HILOG_ERROR("No match moduleName found");
811 return ERR_APPEXECFWK_FORM_NO_SUCH_MODULE;
812 }
813
AddDynamicFormInfo(FormInfo & formInfo,int32_t userId)814 ErrCode FormInfoMgr::AddDynamicFormInfo(FormInfo &formInfo, int32_t userId)
815 {
816 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
817 if (iBundleMgr == nullptr) {
818 HILOG_ERROR("get IBundleMgr failed");
819 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
820 }
821
822 BundleInfo bundleInfo;
823 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
824 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(formInfo.bundleName, flag, bundleInfo, userId))) {
825 HILOG_ERROR("get bundleInfo failed");
826 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
827 }
828
829 ErrCode errCode = CheckDynamicFormInfo(formInfo, bundleInfo);
830 if (errCode != ERR_OK) {
831 HILOG_ERROR("fail CheckDynamicFormInfo");
832 return errCode;
833 }
834
835 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
836 auto bundleFormInfoIter = bundleFormInfoMap_.find(formInfo.bundleName);
837 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
838 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
839 bundleFormInfoPtr = bundleFormInfoIter->second;
840 } else {
841 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(formInfo.bundleName);
842 }
843
844 return bundleFormInfoPtr->AddDynamicFormInfo(formInfo, userId);
845 }
846
RemoveDynamicFormInfo(const std::string & bundleName,const std::string & moduleName,const std::string & formName,int32_t userId)847 ErrCode FormInfoMgr::RemoveDynamicFormInfo(const std::string &bundleName, const std::string &moduleName,
848 const std::string &formName, int32_t userId)
849 {
850 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
851 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
852 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
853 HILOG_ERROR("no forms found in bundle %{public}s", bundleName.c_str());
854 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
855 }
856
857 return bundleFormInfoIter->second->RemoveDynamicFormInfo(moduleName, formName, userId);
858 }
859
RemoveAllDynamicFormsInfo(const std::string & bundleName,int32_t userId)860 ErrCode FormInfoMgr::RemoveAllDynamicFormsInfo(const std::string &bundleName, int32_t userId)
861 {
862 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
863 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
864 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
865 HILOG_ERROR("no forms found in bundle %{public}s", bundleName.c_str());
866 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
867 }
868
869 return bundleFormInfoIter->second->RemoveAllDynamicFormsInfo(userId);
870 }
871
GetOrCreateBundleFromInfo(const std::string & bundleName)872 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
873 {
874 {
875 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
876 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
877 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
878 // found
879 return bundleFormInfoIter->second;
880 }
881 }
882
883 // not found
884 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
885 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
886 // try to find again
887 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
888 // found
889 return bundleFormInfoIter->second;
890 }
891 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
892 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
893 return bundleFormInfoPtr;
894 }
895
IsCaller(const std::string & bundleName)896 bool FormInfoMgr::IsCaller(const std::string& bundleName)
897 {
898 auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
899 if (bms == nullptr) {
900 HILOG_ERROR("fail get Bundle Mgr");
901 return false;
902 }
903 AppExecFwk::BundleInfo bundleInfo;
904 bool ret = IN_PROCESS_CALL(
905 bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
906 if (!ret) {
907 HILOG_ERROR("get bundleInfo failed");
908 return false;
909 }
910 auto callerToken = IPCSkeleton::GetCallingTokenID();
911 if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
912 return true;
913 }
914 return false;
915 }
916
CheckBundlePermission()917 bool FormInfoMgr::CheckBundlePermission()
918 {
919 if (FormUtil::IsSACall()) {
920 return true;
921 }
922 if (FormUtil::VerifyCallingPermission(AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
923 return true;
924 }
925 HILOG_ERROR("Permission verification failed");
926 return false;
927 }
928
ReloadFormInfos(const int32_t userId)929 ErrCode FormInfoMgr::ReloadFormInfos(const int32_t userId)
930 {
931 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
932 HILOG_INFO("userId:%{public}d", userId);
933 std::map<std::string, std::uint32_t> bundleVersionMap {};
934 ErrCode result = GetBundleVersionMap(bundleVersionMap, userId);
935 if (result != ERR_OK) {
936 return result;
937 }
938 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
939 hasReloadedFormInfosState_ = false;
940 UpdateBundleFormInfos(bundleVersionMap, userId);
941 for (auto const &bundleVersionPair : bundleVersionMap) {
942 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleVersionPair.first);
943 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
944 if (errCode != ERR_OK || bundleFormInfoPtr->Empty()) {
945 continue;
946 }
947 bundleFormInfoMap_[bundleVersionPair.first] = bundleFormInfoPtr;
948 HILOG_INFO("add forms info success, bundleName=%{public}s, versionCode:%{public}d",
949 bundleVersionPair.first.c_str(), bundleVersionPair.second);
950 }
951 hasReloadedFormInfosState_ = true;
952 bool publishRet = PublishFmsReadyEvent();
953 if (!publishRet) {
954 HILOG_ERROR("failed to publish fmsIsReady event with permission");
955 }
956 HILOG_INFO("end, formInfoMapSize:%{public}zu", bundleFormInfoMap_.size());
957 return ERR_OK;
958 }
959
PublishFmsReadyEvent()960 bool FormInfoMgr::PublishFmsReadyEvent()
961 {
962 HILOG_INFO("publish fmsIsReady event");
963 Want eventWant;
964 eventWant.SetAction(FMS_IS_READY_EVENT);
965 CommonEventData eventData;
966 eventData.SetWant(eventWant);
967 EventFwk::CommonEventPublishInfo publishInfo;
968 publishInfo.SetSubscriberPermissions({PERMISSION_REQUIRE_FORM});
969 bool ret = EventFwk::CommonEventManager::PublishCommonEvent(eventData, publishInfo);
970 return ret;
971 }
972
HasReloadedFormInfos()973 bool FormInfoMgr::HasReloadedFormInfos()
974 {
975 HILOG_DEBUG("Reloaded Form Infos state %{public}d", hasReloadedFormInfosState_);
976 return hasReloadedFormInfosState_;
977 }
978
GetBundleVersionMap(std::map<std::string,std::uint32_t> & bundleVersionMap,int32_t userId)979 ErrCode FormInfoMgr::GetBundleVersionMap(std::map<std::string, std::uint32_t> &bundleVersionMap, int32_t userId)
980 {
981 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
982 if (iBundleMgr == nullptr) {
983 HILOG_ERROR("get IBundleMgr failed");
984 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
985 }
986
987 std::vector<ExtensionAbilityInfo> extensionInfos {};
988 if (!IN_PROCESS_CALL(iBundleMgr->QueryExtensionAbilityInfos(ExtensionAbilityType::FORM, userId, extensionInfos))) {
989 HILOG_ERROR("get extension infos failed");
990 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
991 }
992
993 std::vector<BundleInfo> bundleInfos {};
994 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfos(GET_BUNDLE_WITH_ABILITIES, bundleInfos, userId))) {
995 HILOG_ERROR("get bundle infos failed");
996 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
997 }
998
999 // get names of bundles that must contain stage forms
1000 for (auto const &extensionInfo : extensionInfos) {
1001 bundleVersionMap.insert(std::make_pair(extensionInfo.bundleName, extensionInfo.applicationInfo.versionCode));
1002 }
1003 // get names of bundles that may contain fa forms
1004 for (auto const &bundleInfo : bundleInfos) {
1005 if (!bundleInfo.abilityInfos.empty() && !bundleInfo.abilityInfos[0].isStageBasedModel) {
1006 bundleVersionMap.insert(std::make_pair(bundleInfo.name, bundleInfo.versionCode));
1007 }
1008 }
1009 return ERR_OK;
1010 }
1011
UpdateBundleFormInfos(std::map<std::string,std::uint32_t> & bundleVersionMap,int32_t userId)1012 void FormInfoMgr::UpdateBundleFormInfos(std::map<std::string, std::uint32_t> &bundleVersionMap, int32_t userId)
1013 {
1014 std::string versionCode;
1015 FormInfoRdbStorageMgr::GetInstance().GetFormVersionCode(versionCode);
1016 bool isNeedUpdateAll = versionCode.empty() ||
1017 Constants::FORM_VERSION_CODE > FormUtil::ConvertStringToInt(versionCode);
1018 HILOG_INFO("bundle number:%{public}zu, old versionCode:%{public}s, new versionCode:%{public}d",
1019 bundleVersionMap.size(), versionCode.c_str(), Constants::FORM_VERSION_CODE);
1020 for (auto const &bundleFormInfoPair : bundleFormInfoMap_) {
1021 const std::string &bundleName = bundleFormInfoPair.first;
1022 auto bundleVersionPair = bundleVersionMap.find(bundleName);
1023 if (bundleVersionPair == bundleVersionMap.end()) {
1024 bundleFormInfoPair.second->Remove(userId);
1025 HILOG_INFO("remove forms info success, bundleName=%{public}s", bundleName.c_str());
1026 continue;
1027 }
1028 if (!isNeedUpdateAll) {
1029 uint32_t newVersionCode = bundleVersionPair->second;
1030 uint32_t oldVersionCode = bundleFormInfoPair.second->GetVersionCode(userId);
1031 HILOG_INFO("bundleName=%{public}s, bundle version old:%{public}d, new:%{public}d",
1032 bundleName.c_str(), oldVersionCode, newVersionCode);
1033 if (oldVersionCode == newVersionCode) {
1034 bundleVersionMap.erase(bundleVersionPair);
1035 continue;
1036 }
1037 }
1038 bundleVersionMap.erase(bundleVersionPair);
1039 bundleFormInfoPair.second->UpdateStaticFormInfos(userId);
1040 HILOG_INFO("update forms info success, bundleName=%{public}s", bundleName.c_str());
1041 }
1042 if (isNeedUpdateAll) {
1043 FormInfoRdbStorageMgr::GetInstance().UpdateFormVersionCode();
1044 }
1045 }
1046
GetAppFormVisibleNotifyByBundleName(const std::string & bundleName,int32_t providerUserId,bool & appFormVisibleNotify)1047 ErrCode FormInfoMgr::GetAppFormVisibleNotifyByBundleName(const std::string &bundleName,
1048 int32_t providerUserId, bool &appFormVisibleNotify)
1049 {
1050 std::lock_guard<std::mutex> lock(appFormVisibleNotifyMapMutex_);
1051 auto iter = appFormVisibleNotifyMap_.find(bundleName);
1052 if (iter == appFormVisibleNotifyMap_.end()) {
1053 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
1054 if (iBundleMgr == nullptr) {
1055 HILOG_ERROR("get IBundleMgr failed");
1056 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
1057 }
1058 AppExecFwk::ApplicationInfo info;
1059 if (!IN_PROCESS_CALL(iBundleMgr->GetApplicationInfo(bundleName,
1060 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, providerUserId, info))) {
1061 HILOG_ERROR("get ApplicationInfo failed");
1062 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
1063 }
1064 appFormVisibleNotifyMap_.emplace(bundleName, info.formVisibleNotify);
1065 appFormVisibleNotify = info.formVisibleNotify;
1066 HILOG_INFO("bundleName=%{public}s, appFormVisibleNotify=%{public}d", bundleName.c_str(), appFormVisibleNotify);
1067 } else {
1068 appFormVisibleNotify = iter->second;
1069 }
1070 return ERR_OK;
1071 }
1072
IsMultiAppForm(const FormInfo & formInfo)1073 bool FormInfoMgr::IsMultiAppForm(const FormInfo &formInfo)
1074 {
1075 bool isMultiAppForm = false;
1076 for (auto dataIter = formInfo.customizeDatas.begin(); dataIter != formInfo.customizeDatas.end();) {
1077 if (Constants::IS_MULTI_APP_FORM == dataIter->name && Constants::IS_MULTI_APP_FORM_TRUE == dataIter->value) {
1078 isMultiAppForm = true;
1079 break;
1080 }
1081 ++dataIter;
1082 }
1083 return isMultiAppForm;
1084 }
1085 } // namespace AppExecFwk
1086 } // namespace OHOS
1087