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