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