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