• 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_info_storage.h"
23 #include "form_info_rdb_storage_mgr.h"
24 #include "form_mgr_errors.h"
25 #include "form_util.h"
26 #include "in_process_call_wrapper.h"
27 #include "ipc_skeleton.h"
28 #include "json_serializer.h"
29 #include "permission_verification.h"
30 
31 namespace OHOS {
32 namespace AppExecFwk {
33 namespace {
34 const std::string FORM_METADATA_NAME = "ohos.extension.form";
35 } // namespace
36 
LoadFormConfigInfoByBundleName(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)37 ErrCode FormInfoHelper::LoadFormConfigInfoByBundleName(const std::string &bundleName, std::vector<FormInfo> &formInfos,
38     int32_t userId)
39 {
40     if (bundleName.empty()) {
41         HILOG_ERROR("bundleName is invalid");
42         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
43     }
44 
45     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
46     if (iBundleMgr == nullptr) {
47         HILOG_ERROR("failed to get IBundleMgr.");
48         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
49     }
50 
51     BundleInfo bundleInfo;
52     if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(bundleName, GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId))) {
53         HILOG_ERROR("failed to get bundle info.");
54         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
55     }
56     // Check if current bundle contains FA forms.
57     if (LoadAbilityFormConfigInfo(bundleInfo, formInfos) != ERR_OK) {
58         HILOG_DEBUG("No fa form config info found for %{public}s.", bundleName.c_str());
59     }
60     // Check if current bundle contains Stage forms.
61     if (LoadStageFormConfigInfo(bundleInfo, formInfos) != ERR_OK) {
62         HILOG_DEBUG("No stage form config info found for %{public}s.", bundleName.c_str());
63     }
64     return ERR_OK;
65 }
66 
LoadStageFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)67 ErrCode FormInfoHelper::LoadStageFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
68 {
69     std::shared_ptr<BundleMgrClient> client = DelayedSingleton<BundleMgrClient>::GetInstance();
70     if (client == nullptr) {
71         HILOG_ERROR("failed to get BundleMgrClient.");
72         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
73     }
74 
75     std::shared_ptr<OHOS::Global::Resource::ResourceManager> resourceManager = GetResourceManager(bundleInfo);
76     if (resourceManager == nullptr) {
77         HILOG_ERROR("InitResourceManager failed");
78         return ERR_APPEXECFWK_FORM_COMMON_CODE;
79     }
80 
81     for (auto const &extensionInfo: bundleInfo.extensionInfos) {
82         if (extensionInfo.type != ExtensionAbilityType::FORM) {
83             continue;
84         }
85 
86         std::vector<std::string> profileInfos {};
87         if (!client->GetResConfigFile(extensionInfo, FORM_METADATA_NAME, profileInfos)) {
88             HILOG_ERROR("failed to get form metadata.");
89             continue;
90         }
91 
92         for (const auto &profileInfo: profileInfos) {
93             std::vector<ExtensionFormInfo> extensionFormInfos;
94             ErrCode errCode = ExtensionFormProfile::TransformTo(profileInfo, extensionFormInfos);
95             if (errCode != ERR_OK) {
96                 HILOG_WARN("failed to transform profile to extension form info");
97                 continue;
98             }
99             for (const auto &extensionFormInfo: extensionFormInfos) {
100                 FormInfo formInfo(extensionInfo, extensionFormInfo);
101                 if (GetFormInfoDescription(resourceManager, formInfo) != ERR_OK) {
102                     HILOG_INFO("Get FormInfo Description fail");
103                 }
104                 formInfos.emplace_back(formInfo);
105             }
106         }
107     }
108     return ERR_OK;
109 }
110 
LoadAbilityFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)111 ErrCode FormInfoHelper::LoadAbilityFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
112 {
113     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
114     if (iBundleMgr == nullptr) {
115         HILOG_ERROR("failed to get IBundleMgr.");
116         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
117     }
118     std::shared_ptr<OHOS::Global::Resource::ResourceManager> resourceManager = GetResourceManager(bundleInfo);
119     if (resourceManager == nullptr) {
120         HILOG_ERROR("InitResourceManager failed");
121         return ERR_APPEXECFWK_FORM_COMMON_CODE;
122     }
123     const std::string &bundleName = bundleInfo.name;
124     for (const auto &modelInfo: bundleInfo.hapModuleInfos) {
125         const std::string &moduleName = modelInfo.moduleName;
126         std::vector<FormInfo> formInfoVec {};
127         if (!IN_PROCESS_CALL(iBundleMgr->GetFormsInfoByModule(bundleName, moduleName, formInfoVec))) {
128             continue;
129         }
130         for (auto &formInfo: formInfoVec) {
131             if (GetFormInfoDescription(resourceManager, formInfo) != ERR_OK) {
132                 HILOG_INFO("Get FormInfo Description fail");
133             }
134             formInfos.emplace_back(formInfo);
135         }
136     }
137 
138     return ERR_OK;
139 }
GetResourceManager(const BundleInfo & bundleInfo)140 std::shared_ptr<Global::Resource::ResourceManager> FormInfoHelper::GetResourceManager(const BundleInfo &bundleInfo)
141 {
142     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
143     if (resourceManager == nullptr) {
144         HILOG_ERROR("InitResourceManager failed");
145         return nullptr;
146     }
147     for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
148         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
149         if (!moduleResPath.empty()) {
150             HILOG_INFO("DistributedBms::InitResourceManager, moduleResPath: %{private}s", moduleResPath.c_str());
151             if (!resourceManager->AddResource(moduleResPath.c_str())) {
152                 HILOG_ERROR("DistributedBms::InitResourceManager AddResource failed");
153             }
154         }
155     }
156     return resourceManager;
157 }
158 
GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,FormInfo & formInfo)159 ErrCode FormInfoHelper::GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager, FormInfo &formInfo)
160 {
161     if (formInfo.descriptionId != 0) {
162         std::string description;
163         auto state = resourceManager->GetStringById(static_cast<uint32_t>(formInfo.descriptionId), description);
164         if (state != OHOS::Global::Resource::RState::SUCCESS) {
165             HILOG_ERROR("ResourceManager GetStringById failed");
166             return ERR_APPEXECFWK_FORM_COMMON_CODE;
167         }
168         formInfo.description = description;
169     }
170     return ERR_OK;
171 }
172 
BundleFormInfo(const std::string & bundleName)173 BundleFormInfo::BundleFormInfo(const std::string &bundleName) : bundleName_(bundleName)
174 {
175 }
176 
InitFromJson(const std::string & formInfoStoragesJson)177 ErrCode BundleFormInfo::InitFromJson(const std::string &formInfoStoragesJson)
178 {
179     nlohmann::json jsonObject = nlohmann::json::parse(formInfoStoragesJson, nullptr, false);
180     if (jsonObject.is_discarded() || !jsonObject.is_array()) {
181         HILOG_ERROR("bad profile");
182         return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
183     }
184     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
185     auto formInfoStorages = jsonObject.get<std::vector<AAFwk::FormInfoStorage>>();
186     for (const auto &item : formInfoStorages) {
187         formInfoStorages_.push_back(item);
188     }
189     return ERR_OK;
190 }
191 
UpdateStaticFormInfos(int32_t userId)192 ErrCode BundleFormInfo::UpdateStaticFormInfos(int32_t userId)
193 {
194     HILOG_INFO("Update static form infos, userId is %{public}d.", userId);
195     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
196     std::vector<FormInfo> formInfos;
197     ErrCode errCode = FormInfoHelper::LoadFormConfigInfoByBundleName(bundleName_, formInfos, userId);
198     if (errCode != ERR_OK) {
199         HILOG_ERROR("LoadFormConfigInfoByBundleName failed, errCode:%{public}d.", errCode);
200         return errCode;
201     }
202 
203     if (!formInfos.empty()) {
204         bool findUser = false;
205         for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end(); ++item) {
206             // Update all user's formInfos
207             HILOG_DEBUG("Update formInfos, user: %{public}d", item->userId);
208             item->formInfos = formInfos;
209             findUser |= (item->userId == userId);
210         }
211         if (!findUser) {
212             HILOG_DEBUG("Add new userId, user: %{public}d", userId);
213             formInfoStorages_.emplace_back(userId, formInfos);
214         }
215     } else {
216         HILOG_DEBUG("The new package of %{public}s does not contain a card, clear it", bundleName_.c_str());
217         formInfoStorages_.clear();
218     }
219 
220     return UpdateFormInfoStorageLocked();
221 }
222 
Remove(int32_t userId)223 ErrCode BundleFormInfo::Remove(int32_t userId)
224 {
225     HILOG_INFO("Remove form infos, userId is %{public}d.", userId);
226     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
227     for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
228         if (item->userId == userId) {
229             item = formInfoStorages_.erase(item);
230         } else {
231             ++item;
232         }
233     }
234     return UpdateFormInfoStorageLocked();
235 }
236 
AddDynamicFormInfo(const FormInfo & formInfo,int32_t userId)237 ErrCode BundleFormInfo::AddDynamicFormInfo(const FormInfo &formInfo, int32_t userId)
238 {
239     HILOG_INFO("Add dynamic form info, userId is %{public}d.", userId);
240     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
241     for (auto &formInfoStorage : formInfoStorages_) {
242         if (formInfoStorage.userId != userId) {
243             continue;
244         }
245         bool isSame = false;
246         for (const auto &item : formInfoStorage.formInfos) {
247             if (item.name == formInfo.name && item.moduleName == formInfo.moduleName) {
248                 isSame = true;
249                 break;
250             }
251         }
252 
253         if (isSame) {
254             HILOG_ERROR("The same form already exists");
255             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
256         }
257         formInfoStorage.formInfos.push_back(formInfo);
258         return UpdateFormInfoStorageLocked();
259     }
260     // no match user id
261     std::vector<FormInfo> formInfos;
262     formInfos.push_back(formInfo);
263     formInfoStorages_.emplace_back(userId, formInfos);
264     return UpdateFormInfoStorageLocked();
265 }
266 
RemoveDynamicFormInfo(const std::string & moduleName,const std::string & formName,int32_t userId)267 ErrCode BundleFormInfo::RemoveDynamicFormInfo(const std::string &moduleName, const std::string &formName,
268                                               int32_t userId)
269 {
270     HILOG_INFO("remove dynamic form 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         for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
277             if (item->name != formName || item->moduleName != moduleName) {
278                 ++item;
279                 continue;
280             }
281             // form found
282             if (item->isStatic) {
283                 HILOG_ERROR("The specified form info is static, can not be removed.");
284                 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
285             }
286             item = formInfoStorage.formInfos.erase(item);
287             return UpdateFormInfoStorageLocked();
288         }
289     }
290     return ERR_APPEXECFWK_FORM_INVALID_PARAM;
291 }
292 
RemoveAllDynamicFormsInfo(int32_t userId)293 ErrCode BundleFormInfo::RemoveAllDynamicFormsInfo(int32_t userId)
294 {
295     HILOG_INFO("remove all dynamic forms info, userId is %{public}d.", userId);
296     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
297     int32_t numRemoved = 0;
298     for (auto &formInfoStorage : formInfoStorages_) {
299         if (formInfoStorage.userId != userId) {
300             continue;
301         }
302         for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
303             if (!item->isStatic) {
304                 ++numRemoved;
305                 item = formInfoStorage.formInfos.erase(item);
306             } else {
307                 ++item;
308             }
309         }
310         break;
311     }
312     if (numRemoved > 0) {
313         HILOG_ERROR("%{public}d dynamic forms info removed.", numRemoved);
314         return UpdateFormInfoStorageLocked();
315     }
316     return ERR_OK;
317 }
318 
Empty() const319 bool BundleFormInfo::Empty() const
320 {
321     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
322     return formInfoStorages_.empty();
323 }
324 
GetAllFormsInfo(std::vector<FormInfo> & formInfos,int32_t userId)325 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos, int32_t userId)
326 {
327     HILOG_INFO("%{public}s begin.",  __func__);
328     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
329     userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
330     for (const auto &item : formInfoStorages_) {
331         item.GetAllFormsInfo(userId, formInfos);
332     }
333     return ERR_OK;
334 }
335 
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos)336 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos)
337 {
338     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
339     int32_t userId = FormUtil::GetCurrentAccountId();
340     for (const auto &item : formInfoStorages_) {
341         item.GetFormsInfoByModule(userId, moduleName, formInfos);
342     }
343     return ERR_OK;
344 }
345 
UpdateFormInfoStorageLocked()346 ErrCode BundleFormInfo::UpdateFormInfoStorageLocked()
347 {
348     ErrCode errCode;
349     if (formInfoStorages_.empty()) {
350         errCode = FormInfoRdbStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
351     } else {
352         nlohmann::json jsonObject = formInfoStorages_;
353         if (jsonObject.is_discarded()) {
354             HILOG_ERROR("bad form infos.");
355             return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
356         }
357         std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
358         errCode = FormInfoRdbStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
359     }
360     return errCode;
361 }
362 
FormInfoMgr()363 FormInfoMgr::FormInfoMgr()
364 {
365     HILOG_INFO("FormInfoMgr is created");
366 }
367 
368 FormInfoMgr::~FormInfoMgr() = default;
369 
Start()370 ErrCode FormInfoMgr::Start()
371 {
372     std::vector<std::pair<std::string, std::string>> formInfoStorages;
373     ErrCode errCode = FormInfoRdbStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
374     if (errCode != ERR_OK) {
375         HILOG_ERROR("LoadFormInfos failed.");
376         return errCode;
377     }
378 
379     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
380     for (const auto &item: formInfoStorages) {
381         const std::string &bundleName = item.first;
382         const std::string &formInfoStoragesJson = item.second;
383         auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
384         errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
385         if (errCode != ERR_OK) {
386             continue;
387         }
388         HILOG_INFO("load bundle %{public}s form infos success.", bundleName.c_str());
389         bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
390     }
391     HILOG_INFO("load bundle form infos from db done.");
392     return ERR_OK;
393 }
394 
UpdateStaticFormInfos(const std::string & bundleName,int32_t userId)395 ErrCode FormInfoMgr::UpdateStaticFormInfos(const std::string &bundleName, int32_t userId)
396 {
397     if (bundleName.empty()) {
398         HILOG_ERROR("bundleName is empty.");
399         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
400     }
401 
402     std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
403     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
404     auto search = bundleFormInfoMap_.find(bundleName);
405     if (search != bundleFormInfoMap_.end()) {
406         bundleFormInfoPtr = search->second;
407     } else {
408         bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
409     }
410 
411     ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
412     if (errCode != ERR_OK) {
413         return errCode;
414     }
415 
416     if (bundleFormInfoPtr->Empty()) {
417         // no forms found, no need to be inserted into the map
418         return ERR_OK;
419     }
420 
421     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
422     HILOG_INFO("update forms info success, bundleName=%{public}s.", bundleName.c_str());
423     return ERR_OK;
424 }
425 
Remove(const std::string & bundleName,int32_t userId)426 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
427 {
428     if (bundleName.empty()) {
429         HILOG_ERROR("bundleName is empty.");
430         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
431     }
432 
433     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
434     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
435     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
436         // BundleFormInfo not found, no need to remove
437         return ERR_OK;
438     }
439 
440     ErrCode errCode = ERR_OK;
441     if (bundleFormInfoIter->second != nullptr) {
442         errCode = bundleFormInfoIter->second->Remove(userId);
443     }
444 
445     if (bundleFormInfoIter->second && bundleFormInfoIter->second->Empty()) {
446         bundleFormInfoMap_.erase(bundleFormInfoIter);
447     }
448     HILOG_INFO("remove forms info success, bundleName=%{public}s.", bundleName.c_str());
449     return errCode;
450 }
451 
GetAllFormsInfo(std::vector<FormInfo> & formInfos)452 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
453 {
454     bool hasPermission = CheckBundlePermission();
455     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
456     if (!hasPermission) {
457         HILOG_ERROR("CheckBundlePermission is failed.");
458         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
459     }
460     for (const auto &bundleFormInfo : bundleFormInfoMap_) {
461         if (bundleFormInfo.second != nullptr) {
462             bundleFormInfo.second->GetAllFormsInfo(formInfos);
463         }
464     }
465     return ERR_OK;
466 }
467 
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)468 ErrCode FormInfoMgr::GetFormsInfoByBundle(
469     const std::string &bundleName, std::vector<FormInfo> &formInfos, int32_t userId)
470 {
471     if (bundleName.empty()) {
472         HILOG_ERROR("bundleName is empty.");
473         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
474     }
475 
476     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
477         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
478     }
479 
480     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
481     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
482     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
483         HILOG_ERROR("no forms found.");
484         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
485     }
486 
487     if (bundleFormInfoIter->second != nullptr) {
488         bundleFormInfoIter->second->GetAllFormsInfo(formInfos, userId);
489     }
490     return ERR_OK;
491 }
492 
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos)493 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
494                                           std::vector<FormInfo> &formInfos)
495 {
496     if (bundleName.empty()) {
497         HILOG_ERROR("bundleName is empty.");
498         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
499     }
500 
501     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
502         HILOG_ERROR("CheckBundlePermission and IsCaller failed.");
503         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
504     }
505 
506     return GetFormsInfoByModuleWithoutCheck(bundleName, moduleName, formInfos);
507 }
508 
GetFormsInfoByModuleWithoutCheck(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos)509 ErrCode FormInfoMgr::GetFormsInfoByModuleWithoutCheck(const std::string &bundleName, const std::string &moduleName,
510     std::vector<FormInfo> &formInfos)
511 {
512     if (bundleName.empty()) {
513         HILOG_ERROR("bundleName is empty.");
514         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
515     }
516 
517     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
518     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
519     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
520         HILOG_ERROR("no forms found for %{public}s.", bundleName.c_str());
521         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
522     }
523 
524     if (bundleFormInfoIter->second != nullptr) {
525         bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos);
526     }
527     return ERR_OK;
528 }
529 
GetFormsInfoByRecord(const FormRecord & formRecord,FormInfo & formInfo)530 ErrCode FormInfoMgr::GetFormsInfoByRecord(const FormRecord &formRecord, FormInfo &formInfo)
531 {
532     std::vector<FormInfo> formInfos;
533     {
534         std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
535         auto bundleFormInfoIter = bundleFormInfoMap_.find(formRecord.bundleName);
536         if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
537             HILOG_ERROR("no forms found for %{public}s.", formRecord.bundleName.c_str());
538             return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
539         }
540 
541         if (bundleFormInfoIter->second == nullptr) {
542             HILOG_ERROR("BundleFormInfo is nullptr, GetFormsInfoByModule failed.");
543             return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
544         }
545 
546         bundleFormInfoIter->second->GetFormsInfoByModule(formRecord.moduleName, formInfos);
547     }
548     for (const FormInfo &info : formInfos) {
549         if (info.name == formRecord.formName) {
550             formInfo = info;
551             break;
552         }
553     }
554     return formInfo.name.empty() ? ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED : ERR_OK;
555 }
556 
CheckDynamicFormInfo(FormInfo & formInfo,const BundleInfo & bundleInfo)557 ErrCode FormInfoMgr::CheckDynamicFormInfo(FormInfo &formInfo, const BundleInfo &bundleInfo)
558 {
559     for (auto &moduleInfo : bundleInfo.hapModuleInfos) {
560         if (formInfo.moduleName != moduleInfo.moduleName) {
561             continue;
562         }
563         for (auto &abilityInfo : moduleInfo.abilityInfos) {
564             if (formInfo.abilityName != abilityInfo.name) {
565                 continue;
566             }
567             formInfo.src = "";
568             return ERR_OK;
569         }
570         for (auto &extensionInfos : moduleInfo.extensionInfos) {
571             if (formInfo.abilityName != extensionInfos.name) {
572                 continue;
573             }
574             formInfo.src = "./js/" + formInfo.name + "/pages/index/index";
575             return ERR_OK;
576         }
577         HILOG_ERROR("No match abilityName found");
578         return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY;
579     }
580 
581     HILOG_ERROR("No match moduleName found");
582     return ERR_APPEXECFWK_FORM_NO_SUCH_MODULE;
583 }
584 
AddDynamicFormInfo(FormInfo & formInfo,int32_t userId)585 ErrCode FormInfoMgr::AddDynamicFormInfo(FormInfo &formInfo, int32_t userId)
586 {
587     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
588     if (iBundleMgr == nullptr) {
589         HILOG_ERROR("failed to get IBundleMgr.");
590         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
591     }
592 
593     BundleInfo bundleInfo;
594     int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
595     if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(formInfo.bundleName, flag, bundleInfo, userId))) {
596         HILOG_ERROR("failed to get bundle info.");
597         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
598     }
599 
600     ErrCode errCode = CheckDynamicFormInfo(formInfo, bundleInfo);
601     if (errCode != ERR_OK) {
602         HILOG_ERROR("failed to CheckDynamicFormInfo.");
603         return errCode;
604     }
605 
606     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
607     auto bundleFormInfoIter = bundleFormInfoMap_.find(formInfo.bundleName);
608     std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
609     if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
610         bundleFormInfoPtr = bundleFormInfoIter->second;
611     } else {
612         bundleFormInfoPtr = std::make_shared<BundleFormInfo>(formInfo.bundleName);
613     }
614 
615     return bundleFormInfoPtr->AddDynamicFormInfo(formInfo, userId);
616 }
617 
RemoveDynamicFormInfo(const std::string & bundleName,const std::string & moduleName,const std::string & formName,int32_t userId)618 ErrCode FormInfoMgr::RemoveDynamicFormInfo(const std::string &bundleName, const std::string &moduleName,
619                                            const std::string &formName, int32_t userId)
620 {
621     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
622     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
623     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
624         HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
625         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
626     }
627 
628     return bundleFormInfoIter->second->RemoveDynamicFormInfo(moduleName, formName, userId);
629 }
630 
RemoveAllDynamicFormsInfo(const std::string & bundleName,int32_t userId)631 ErrCode FormInfoMgr::RemoveAllDynamicFormsInfo(const std::string &bundleName, int32_t userId)
632 {
633     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
634     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
635     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
636         HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
637         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
638     }
639 
640     return bundleFormInfoIter->second->RemoveAllDynamicFormsInfo(userId);
641 }
642 
GetOrCreateBundleFromInfo(const std::string & bundleName)643 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
644 {
645     {
646         std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
647         auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
648         if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
649             // found
650             return bundleFormInfoIter->second;
651         }
652     }
653 
654     // not found
655     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
656     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
657     // try to find again
658     if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
659         // found
660         return bundleFormInfoIter->second;
661     }
662     auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
663     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
664     return bundleFormInfoPtr;
665 }
666 
IsCaller(const std::string & bundleName)667 bool FormInfoMgr::IsCaller(const std::string& bundleName)
668 {
669     auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
670     if (bms == nullptr) {
671         HILOG_ERROR("Failed to get Bundle Mgr.");
672         return false;
673     }
674     AppExecFwk::BundleInfo bundleInfo;
675     bool ret = IN_PROCESS_CALL(
676         bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
677     if (!ret) {
678         HILOG_ERROR("Failed to get bundle info.");
679         return false;
680     }
681     auto callerToken = IPCSkeleton::GetCallingTokenID();
682     if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
683         return true;
684     }
685     return false;
686 }
687 
CheckBundlePermission()688 bool FormInfoMgr::CheckBundlePermission()
689 {
690     auto isSaCall = FormUtil::IsSACall();
691     if (isSaCall) {
692         return true;
693     }
694     auto isCallingPerm = FormUtil::VerifyCallingPermission(
695         AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
696     if (isCallingPerm) {
697         return true;
698     }
699     HILOG_ERROR("Permission verification failed");
700     return false;
701 }
702 
ReloadFormInfos(const int32_t userId)703 ErrCode FormInfoMgr::ReloadFormInfos(const int32_t userId)
704 {
705     HILOG_INFO("ReloadFormInfos userId: %{public}d.", userId);
706     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
707     if (iBundleMgr == nullptr) {
708         HILOG_ERROR("failed to get IBundleMgr.");
709         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
710     }
711 
712     std::vector<ApplicationInfo> appInfos {};
713     if (!IN_PROCESS_CALL(iBundleMgr->GetApplicationInfos(GET_BASIC_APPLICATION_INFO, userId, appInfos))) {
714         HILOG_ERROR("failed to get Application info.");
715         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
716     }
717 
718     std::set<std::string> bundleNameSet {};
719     for (auto const &appInfo : appInfos) {
720         bundleNameSet.emplace(appInfo.bundleName);
721     }
722 
723     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
724     for (auto const &bundleFormInfoPair : bundleFormInfoMap_) {
725         const std::string &bundleName = bundleFormInfoPair.first;
726         auto setFindIter = bundleNameSet.find(bundleName);
727         if (setFindIter == bundleNameSet.end()) {
728             bundleFormInfoPair.second->Remove(userId);
729             HILOG_DEBUG("remove forms info success, bundleName=%{public}s", bundleName.c_str());
730             continue;
731         }
732         bundleNameSet.erase(setFindIter);
733         bundleFormInfoPair.second->UpdateStaticFormInfos(userId);
734         HILOG_DEBUG("update forms info success, bundleName=%{public}s", bundleName.c_str());
735     }
736 
737     for (auto const &bundleName : bundleNameSet) {
738         std::shared_ptr<BundleFormInfo> bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
739         ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
740         if (errCode != ERR_OK || bundleFormInfoPtr->Empty()) {
741             continue;
742         }
743         bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
744         HILOG_DEBUG("add forms info success, bundleName=%{public}s", bundleName.c_str());
745     }
746     return ERR_OK;
747 }
748 }  // namespace AppExecFwk
749 }  // namespace OHOS
750