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