• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "form_bms_helper.h"
21 #include "form_info_storage.h"
22 #include "form_info_rdb_storage_mgr.h"
23 #include "form_mgr_errors.h"
24 #include "form_util.h"
25 #include "hilog_wrapper.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_INFO("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_INFO("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.resourcePath;
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()) {
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     }
216 
217     return UpdateFormInfoStorageLocked();
218 }
219 
Remove(int32_t userId)220 ErrCode BundleFormInfo::Remove(int32_t userId)
221 {
222     HILOG_INFO("Remove form infos, userId is %{public}d.", userId);
223     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
224     for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
225         if (item->userId == userId) {
226             item = formInfoStorages_.erase(item);
227         } else {
228             ++item;
229         }
230     }
231     return UpdateFormInfoStorageLocked();
232 }
233 
AddDynamicFormInfo(const FormInfo & formInfo,int32_t userId)234 ErrCode BundleFormInfo::AddDynamicFormInfo(const FormInfo &formInfo, int32_t userId)
235 {
236     HILOG_INFO("Add dynamic form info, userId is %{public}d.", userId);
237     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
238     for (auto &formInfoStorage : formInfoStorages_) {
239         if (formInfoStorage.userId != userId) {
240             continue;
241         }
242         bool isSame = false;
243         for (const auto &item : formInfoStorage.formInfos) {
244             if (item.name == formInfo.name && item.moduleName == formInfo.moduleName) {
245                 isSame = true;
246                 break;
247             }
248         }
249 
250         if (isSame) {
251             HILOG_ERROR("The same form already exists");
252             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
253         }
254         formInfoStorage.formInfos.push_back(formInfo);
255         return UpdateFormInfoStorageLocked();
256     }
257     // no match user id
258     std::vector<FormInfo> formInfos;
259     formInfos.push_back(formInfo);
260     formInfoStorages_.emplace_back(userId, formInfos);
261     return UpdateFormInfoStorageLocked();
262 }
263 
RemoveDynamicFormInfo(const std::string & moduleName,const std::string & formName,int32_t userId)264 ErrCode BundleFormInfo::RemoveDynamicFormInfo(const std::string &moduleName, const std::string &formName,
265                                               int32_t userId)
266 {
267     HILOG_INFO("remove dynamic form info, userId is %{public}d.", userId);
268     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
269     for (auto &formInfoStorage : formInfoStorages_) {
270         if (formInfoStorage.userId != userId) {
271             continue;
272         }
273         for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
274             if (item->name != formName || item->moduleName != moduleName) {
275                 ++item;
276                 continue;
277             }
278             // form found
279             if (item->isStatic) {
280                 HILOG_ERROR("The specified form info is static, can not be removed.");
281                 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
282             }
283             item = formInfoStorage.formInfos.erase(item);
284             return UpdateFormInfoStorageLocked();
285         }
286     }
287     return ERR_APPEXECFWK_FORM_INVALID_PARAM;
288 }
289 
RemoveAllDynamicFormsInfo(int32_t userId)290 ErrCode BundleFormInfo::RemoveAllDynamicFormsInfo(int32_t userId)
291 {
292     HILOG_INFO("remove all dynamic forms info, userId is %{public}d.", userId);
293     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
294     int32_t numRemoved = 0;
295     for (auto &formInfoStorage : formInfoStorages_) {
296         if (formInfoStorage.userId != userId) {
297             continue;
298         }
299         for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
300             if (!item->isStatic) {
301                 ++numRemoved;
302                 item = formInfoStorage.formInfos.erase(item);
303             } else {
304                 ++item;
305             }
306         }
307         break;
308     }
309     if (numRemoved > 0) {
310         HILOG_ERROR("%{public}d dynamic forms info removed.", numRemoved);
311         return UpdateFormInfoStorageLocked();
312     }
313     return ERR_OK;
314 }
315 
Empty() const316 bool BundleFormInfo::Empty() const
317 {
318     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
319     return formInfoStorages_.empty();
320 }
321 
GetAllFormsInfo(std::vector<FormInfo> & formInfos)322 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
323 {
324     HILOG_INFO("%{public}s begin.",  __func__);
325     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
326     int32_t userId = FormUtil::GetCurrentAccountId();
327     for (const auto &item : formInfoStorages_) {
328         item.GetAllFormsInfo(userId, formInfos);
329     }
330     return ERR_OK;
331 }
332 
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos)333 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos)
334 {
335     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
336     int32_t userId = FormUtil::GetCurrentAccountId();
337     for (const auto &item : formInfoStorages_) {
338         item.GetFormsInfoByModule(userId, moduleName, formInfos);
339     }
340     return ERR_OK;
341 }
342 
UpdateFormInfoStorageLocked()343 ErrCode BundleFormInfo::UpdateFormInfoStorageLocked()
344 {
345     ErrCode errCode;
346     if (formInfoStorages_.empty()) {
347         errCode = FormInfoRdbStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
348     } else {
349         nlohmann::json jsonObject = formInfoStorages_;
350         if (jsonObject.is_discarded()) {
351             HILOG_ERROR("bad form infos.");
352             return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
353         }
354         std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
355         errCode = FormInfoRdbStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
356     }
357     return errCode;
358 }
359 
FormInfoMgr()360 FormInfoMgr::FormInfoMgr()
361 {
362     HILOG_INFO("FormInfoMgr is created");
363 }
364 
365 FormInfoMgr::~FormInfoMgr() = default;
366 
Start()367 ErrCode FormInfoMgr::Start()
368 {
369     std::vector<std::pair<std::string, std::string>> formInfoStorages;
370     ErrCode errCode = FormInfoRdbStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
371     if (errCode != ERR_OK) {
372         HILOG_ERROR("LoadFormInfos failed.");
373         return errCode;
374     }
375 
376     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
377     for (const auto &item: formInfoStorages) {
378         const std::string &bundleName = item.first;
379         const std::string &formInfoStoragesJson = item.second;
380         auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
381         errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
382         if (errCode != ERR_OK) {
383             continue;
384         }
385         HILOG_INFO("load bundle %{public}s form infos success.", bundleName.c_str());
386         bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
387     }
388     HILOG_INFO("load bundle form infos from db done.");
389     return ERR_OK;
390 }
391 
UpdateStaticFormInfos(const std::string & bundleName,int32_t userId)392 ErrCode FormInfoMgr::UpdateStaticFormInfos(const std::string &bundleName, int32_t userId)
393 {
394     if (bundleName.empty()) {
395         HILOG_ERROR("bundleName is empty.");
396         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
397     }
398 
399     std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
400     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
401     auto search = bundleFormInfoMap_.find(bundleName);
402     if (search != bundleFormInfoMap_.end()) {
403         bundleFormInfoPtr = search->second;
404     } else {
405         bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
406     }
407 
408     ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
409     if (errCode != ERR_OK) {
410         return errCode;
411     }
412 
413     if (bundleFormInfoPtr->Empty()) {
414         // no forms found, no need to be inserted into the map
415         return ERR_OK;
416     }
417 
418     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
419     HILOG_INFO("update forms info success, bundleName=%{public}s.", bundleName.c_str());
420     return ERR_OK;
421 }
422 
Remove(const std::string & bundleName,int32_t userId)423 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
424 {
425     if (bundleName.empty()) {
426         HILOG_ERROR("bundleName is empty.");
427         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
428     }
429 
430     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
431     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
432     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
433         // BundleFormInfo not found, no need to remove
434         return ERR_OK;
435     }
436 
437     ErrCode errCode = ERR_OK;
438     if (bundleFormInfoIter->second != nullptr) {
439         errCode = bundleFormInfoIter->second->Remove(userId);
440     }
441 
442     if (bundleFormInfoIter->second && bundleFormInfoIter->second->Empty()) {
443         bundleFormInfoMap_.erase(bundleFormInfoIter);
444     }
445     HILOG_INFO("remove forms info success, bundleName=%{public}s.", bundleName.c_str());
446     return errCode;
447 }
448 
GetAllFormsInfo(std::vector<FormInfo> & formInfos)449 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
450 {
451     bool hasPermission = CheckBundlePermission();
452     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
453     if (hasPermission) {
454         for (const auto &bundleFormInfo : bundleFormInfoMap_) {
455             if (bundleFormInfo.second != nullptr) {
456                 bundleFormInfo.second->GetAllFormsInfo(formInfos);
457             }
458         }
459     } else {
460         for (const auto &bundleFormInfo : bundleFormInfoMap_) {
461             if (IsCaller(bundleFormInfo.first)) {
462                 if (bundleFormInfo.second != nullptr) {
463                     bundleFormInfo.second->GetAllFormsInfo(formInfos);
464                 }
465                 return ERR_OK;
466             }
467         }
468     }
469     return ERR_OK;
470 }
471 
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos)472 ErrCode FormInfoMgr::GetFormsInfoByBundle(const std::string &bundleName, std::vector<FormInfo> &formInfos)
473 {
474     if (bundleName.empty()) {
475         HILOG_ERROR("bundleName is empty.");
476         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
477     }
478 
479     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
480         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
481     }
482 
483     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
484     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
485     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
486         HILOG_ERROR("no forms found.");
487         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
488     }
489 
490     if (bundleFormInfoIter->second != nullptr) {
491         bundleFormInfoIter->second->GetAllFormsInfo(formInfos);
492     }
493     return ERR_OK;
494 }
495 
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos)496 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
497                                           std::vector<FormInfo> &formInfos)
498 {
499     if (bundleName.empty()) {
500         HILOG_ERROR("bundleName is empty.");
501         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
502     }
503 
504     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
505         HILOG_ERROR("CheckBundlePermission and IsCaller failed.");
506         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
507     }
508 
509     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
510     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
511     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
512         HILOG_ERROR("no forms found for %{public}s.", bundleName.c_str());
513         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
514     }
515 
516     if (bundleFormInfoIter->second != nullptr) {
517         bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos);
518     }
519     return ERR_OK;
520 }
521 
CheckDynamicFormInfo(FormInfo & formInfo,const BundleInfo & bundleInfo)522 ErrCode FormInfoMgr::CheckDynamicFormInfo(FormInfo &formInfo, const BundleInfo &bundleInfo)
523 {
524     for (auto &moduleInfo : bundleInfo.hapModuleInfos) {
525         if (formInfo.moduleName != moduleInfo.moduleName) {
526             continue;
527         }
528         for (auto &abilityInfo : moduleInfo.abilityInfos) {
529             if (formInfo.abilityName != abilityInfo.name) {
530                 continue;
531             }
532             formInfo.src = "";
533             return ERR_OK;
534         }
535         for (auto &extensionInfos : moduleInfo.extensionInfos) {
536             if (formInfo.abilityName != extensionInfos.name) {
537                 continue;
538             }
539             formInfo.src = "./js/" + formInfo.name + "/pages/index/index";
540             return ERR_OK;
541         }
542         HILOG_ERROR("No match abilityName found");
543         return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY;
544     }
545 
546     HILOG_ERROR("No match moduleName found");
547     return ERR_APPEXECFWK_FORM_NO_SUCH_MODULE;
548 }
549 
AddDynamicFormInfo(FormInfo & formInfo,int32_t userId)550 ErrCode FormInfoMgr::AddDynamicFormInfo(FormInfo &formInfo, int32_t userId)
551 {
552     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
553     if (iBundleMgr == nullptr) {
554         HILOG_ERROR("failed to get IBundleMgr.");
555         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
556     }
557 
558     BundleInfo bundleInfo;
559     int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
560     if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(formInfo.bundleName, flag, bundleInfo, userId))) {
561         HILOG_ERROR("failed to get bundle info.");
562         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
563     }
564 
565     ErrCode errCode = CheckDynamicFormInfo(formInfo, bundleInfo);
566     if (errCode != ERR_OK) {
567         HILOG_ERROR("failed to CheckDynamicFormInfo.");
568         return errCode;
569     }
570 
571     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
572     auto bundleFormInfoIter = bundleFormInfoMap_.find(formInfo.bundleName);
573     std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
574     if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
575         bundleFormInfoPtr = bundleFormInfoIter->second;
576     } else {
577         bundleFormInfoPtr = std::make_shared<BundleFormInfo>(formInfo.bundleName);
578     }
579 
580     return bundleFormInfoPtr->AddDynamicFormInfo(formInfo, userId);
581 }
582 
RemoveDynamicFormInfo(const std::string & bundleName,const std::string & moduleName,const std::string & formName,int32_t userId)583 ErrCode FormInfoMgr::RemoveDynamicFormInfo(const std::string &bundleName, const std::string &moduleName,
584                                            const std::string &formName, int32_t userId)
585 {
586     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
587     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
588     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
589         HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
590         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
591     }
592 
593     return bundleFormInfoIter->second->RemoveDynamicFormInfo(moduleName, formName, userId);
594 }
595 
RemoveAllDynamicFormsInfo(const std::string & bundleName,int32_t userId)596 ErrCode FormInfoMgr::RemoveAllDynamicFormsInfo(const std::string &bundleName, int32_t userId)
597 {
598     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
599     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
600     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
601         HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
602         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
603     }
604 
605     return bundleFormInfoIter->second->RemoveAllDynamicFormsInfo(userId);
606 }
607 
GetOrCreateBundleFromInfo(const std::string & bundleName)608 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
609 {
610     {
611         std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
612         auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
613         if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
614             // found
615             return bundleFormInfoIter->second;
616         }
617     }
618 
619     // not found
620     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
621     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
622     // try to find again
623     if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
624         // found
625         return bundleFormInfoIter->second;
626     }
627     auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
628     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
629     return bundleFormInfoPtr;
630 }
631 
IsCaller(const std::string & bundleName)632 bool FormInfoMgr::IsCaller(const std::string& bundleName)
633 {
634     auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
635     if (bms == nullptr) {
636         HILOG_ERROR("Failed to get Bundle Mgr.");
637         return false;
638     }
639     AppExecFwk::BundleInfo bundleInfo;
640     bool ret = IN_PROCESS_CALL(
641         bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
642     if (!ret) {
643         HILOG_ERROR("Failed to get bundle info.");
644         return false;
645     }
646     auto callerToken = IPCSkeleton::GetCallingTokenID();
647     if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
648         return true;
649     }
650     return false;
651 }
652 
CheckBundlePermission()653 bool FormInfoMgr::CheckBundlePermission()
654 {
655     auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
656     if (isSaCall) {
657         return true;
658     }
659     auto isCallingPerm = AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
660         AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
661     if (isCallingPerm) {
662         return true;
663     }
664     HILOG_ERROR("Permission verification failed");
665     return false;
666 }
667 
ReloadFormInfos(const int32_t userId)668 ErrCode FormInfoMgr::ReloadFormInfos(const int32_t userId)
669 {
670     HILOG_INFO("ReloadFormInfos userId: %{public}d.", userId);
671     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
672     if (iBundleMgr == nullptr) {
673         HILOG_ERROR("failed to get IBundleMgr.");
674         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
675     }
676 
677     std::vector<ApplicationInfo> appInfos {};
678     if (!IN_PROCESS_CALL(iBundleMgr->GetApplicationInfos(GET_BASIC_APPLICATION_INFO, userId, appInfos))) {
679         HILOG_ERROR("failed to get Application info.");
680         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
681     }
682 
683     std::set<std::string> bundleNameSet {};
684     for (auto const &appInfo : appInfos) {
685         bundleNameSet.emplace(appInfo.bundleName);
686     }
687 
688     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
689     for (auto const &bundleFormInfoPair : bundleFormInfoMap_) {
690         const std::string &bundleName = bundleFormInfoPair.first;
691         auto setFindIter = bundleNameSet.find(bundleName);
692         if (setFindIter == bundleNameSet.end()) {
693             bundleFormInfoPair.second->Remove(userId);
694             HILOG_INFO("remove forms info success, bundleName=%{public}s", bundleName.c_str());
695             continue;
696         }
697         bundleNameSet.erase(setFindIter);
698         bundleFormInfoPair.second->UpdateStaticFormInfos(userId);
699         HILOG_INFO("update forms info success, bundleName=%{public}s", bundleName.c_str());
700     }
701 
702     for (auto const &bundleName : bundleNameSet) {
703         std::shared_ptr<BundleFormInfo> bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
704         ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
705         if (errCode != ERR_OK || bundleFormInfoPtr->Empty()) {
706             continue;
707         }
708         bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
709         HILOG_INFO("add forms info success, bundleName=%{public}s", bundleName.c_str());
710     }
711     return ERR_OK;
712 }
713 }  // namespace AppExecFwk
714 }  // namespace OHOS
715