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