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