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