• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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