1 /*
2 * Copyright (c) 2021-2022 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 "form_bms_helper.h"
21 #include "form_info_storage.h"
22 #include "form_info_rdb_storage_mgr.h"
23 #include "form_mgr_errors.h"
24 #include "form_util.h"
25 #include "hilog_wrapper.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_INFO("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_INFO("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.resourcePath;
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()) {
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 }
216
217 return UpdateFormInfoStorageLocked();
218 }
219
Remove(int32_t userId)220 ErrCode BundleFormInfo::Remove(int32_t userId)
221 {
222 HILOG_INFO("Remove form infos, userId is %{public}d.", userId);
223 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
224 for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
225 if (item->userId == userId) {
226 item = formInfoStorages_.erase(item);
227 } else {
228 ++item;
229 }
230 }
231 return UpdateFormInfoStorageLocked();
232 }
233
AddDynamicFormInfo(const FormInfo & formInfo,int32_t userId)234 ErrCode BundleFormInfo::AddDynamicFormInfo(const FormInfo &formInfo, int32_t userId)
235 {
236 HILOG_INFO("Add dynamic form info, userId is %{public}d.", userId);
237 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
238 for (auto &formInfoStorage : formInfoStorages_) {
239 if (formInfoStorage.userId != userId) {
240 continue;
241 }
242 bool isSame = false;
243 for (const auto &item : formInfoStorage.formInfos) {
244 if (item.name == formInfo.name && item.moduleName == formInfo.moduleName) {
245 isSame = true;
246 break;
247 }
248 }
249
250 if (isSame) {
251 HILOG_ERROR("The same form already exists");
252 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
253 }
254 formInfoStorage.formInfos.push_back(formInfo);
255 return UpdateFormInfoStorageLocked();
256 }
257 // no match user id
258 std::vector<FormInfo> formInfos;
259 formInfos.push_back(formInfo);
260 formInfoStorages_.emplace_back(userId, formInfos);
261 return UpdateFormInfoStorageLocked();
262 }
263
RemoveDynamicFormInfo(const std::string & moduleName,const std::string & formName,int32_t userId)264 ErrCode BundleFormInfo::RemoveDynamicFormInfo(const std::string &moduleName, const std::string &formName,
265 int32_t userId)
266 {
267 HILOG_INFO("remove dynamic form info, userId is %{public}d.", userId);
268 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
269 for (auto &formInfoStorage : formInfoStorages_) {
270 if (formInfoStorage.userId != userId) {
271 continue;
272 }
273 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
274 if (item->name != formName || item->moduleName != moduleName) {
275 ++item;
276 continue;
277 }
278 // form found
279 if (item->isStatic) {
280 HILOG_ERROR("The specified form info is static, can not be removed.");
281 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
282 }
283 item = formInfoStorage.formInfos.erase(item);
284 return UpdateFormInfoStorageLocked();
285 }
286 }
287 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
288 }
289
RemoveAllDynamicFormsInfo(int32_t userId)290 ErrCode BundleFormInfo::RemoveAllDynamicFormsInfo(int32_t userId)
291 {
292 HILOG_INFO("remove all dynamic forms info, userId is %{public}d.", userId);
293 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
294 int32_t numRemoved = 0;
295 for (auto &formInfoStorage : formInfoStorages_) {
296 if (formInfoStorage.userId != userId) {
297 continue;
298 }
299 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
300 if (!item->isStatic) {
301 ++numRemoved;
302 item = formInfoStorage.formInfos.erase(item);
303 } else {
304 ++item;
305 }
306 }
307 break;
308 }
309 if (numRemoved > 0) {
310 HILOG_ERROR("%{public}d dynamic forms info removed.", numRemoved);
311 return UpdateFormInfoStorageLocked();
312 }
313 return ERR_OK;
314 }
315
Empty() const316 bool BundleFormInfo::Empty() const
317 {
318 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
319 return formInfoStorages_.empty();
320 }
321
GetAllFormsInfo(std::vector<FormInfo> & formInfos)322 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
323 {
324 HILOG_INFO("%{public}s begin.", __func__);
325 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
326 int32_t userId = FormUtil::GetCurrentAccountId();
327 for (const auto &item : formInfoStorages_) {
328 item.GetAllFormsInfo(userId, formInfos);
329 }
330 return ERR_OK;
331 }
332
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos)333 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos)
334 {
335 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
336 int32_t userId = FormUtil::GetCurrentAccountId();
337 for (const auto &item : formInfoStorages_) {
338 item.GetFormsInfoByModule(userId, moduleName, formInfos);
339 }
340 return ERR_OK;
341 }
342
UpdateFormInfoStorageLocked()343 ErrCode BundleFormInfo::UpdateFormInfoStorageLocked()
344 {
345 ErrCode errCode;
346 if (formInfoStorages_.empty()) {
347 errCode = FormInfoRdbStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
348 } else {
349 nlohmann::json jsonObject = formInfoStorages_;
350 if (jsonObject.is_discarded()) {
351 HILOG_ERROR("bad form infos.");
352 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
353 }
354 std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
355 errCode = FormInfoRdbStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
356 }
357 return errCode;
358 }
359
FormInfoMgr()360 FormInfoMgr::FormInfoMgr()
361 {
362 HILOG_INFO("FormInfoMgr is created");
363 }
364
365 FormInfoMgr::~FormInfoMgr() = default;
366
Start()367 ErrCode FormInfoMgr::Start()
368 {
369 std::vector<std::pair<std::string, std::string>> formInfoStorages;
370 ErrCode errCode = FormInfoRdbStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
371 if (errCode != ERR_OK) {
372 HILOG_ERROR("LoadFormInfos failed.");
373 return errCode;
374 }
375
376 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
377 for (const auto &item: formInfoStorages) {
378 const std::string &bundleName = item.first;
379 const std::string &formInfoStoragesJson = item.second;
380 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
381 errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
382 if (errCode != ERR_OK) {
383 continue;
384 }
385 HILOG_INFO("load bundle %{public}s form infos success.", bundleName.c_str());
386 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
387 }
388 HILOG_INFO("load bundle form infos from db done.");
389 return ERR_OK;
390 }
391
UpdateStaticFormInfos(const std::string & bundleName,int32_t userId)392 ErrCode FormInfoMgr::UpdateStaticFormInfos(const std::string &bundleName, int32_t userId)
393 {
394 if (bundleName.empty()) {
395 HILOG_ERROR("bundleName is empty.");
396 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
397 }
398
399 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
400 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
401 auto search = bundleFormInfoMap_.find(bundleName);
402 if (search != bundleFormInfoMap_.end()) {
403 bundleFormInfoPtr = search->second;
404 } else {
405 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
406 }
407
408 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
409 if (errCode != ERR_OK) {
410 return errCode;
411 }
412
413 if (bundleFormInfoPtr->Empty()) {
414 // no forms found, no need to be inserted into the map
415 return ERR_OK;
416 }
417
418 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
419 HILOG_INFO("update forms info success, bundleName=%{public}s.", bundleName.c_str());
420 return ERR_OK;
421 }
422
Remove(const std::string & bundleName,int32_t userId)423 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
424 {
425 if (bundleName.empty()) {
426 HILOG_ERROR("bundleName is empty.");
427 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
428 }
429
430 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
431 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
432 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
433 // BundleFormInfo not found, no need to remove
434 return ERR_OK;
435 }
436
437 ErrCode errCode = ERR_OK;
438 if (bundleFormInfoIter->second != nullptr) {
439 errCode = bundleFormInfoIter->second->Remove(userId);
440 }
441
442 if (bundleFormInfoIter->second && bundleFormInfoIter->second->Empty()) {
443 bundleFormInfoMap_.erase(bundleFormInfoIter);
444 }
445 HILOG_INFO("remove forms info success, bundleName=%{public}s.", bundleName.c_str());
446 return errCode;
447 }
448
GetAllFormsInfo(std::vector<FormInfo> & formInfos)449 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
450 {
451 bool hasPermission = CheckBundlePermission();
452 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
453 if (hasPermission) {
454 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
455 if (bundleFormInfo.second != nullptr) {
456 bundleFormInfo.second->GetAllFormsInfo(formInfos);
457 }
458 }
459 } else {
460 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
461 if (IsCaller(bundleFormInfo.first)) {
462 if (bundleFormInfo.second != nullptr) {
463 bundleFormInfo.second->GetAllFormsInfo(formInfos);
464 }
465 return ERR_OK;
466 }
467 }
468 }
469 return ERR_OK;
470 }
471
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos)472 ErrCode FormInfoMgr::GetFormsInfoByBundle(const std::string &bundleName, std::vector<FormInfo> &formInfos)
473 {
474 if (bundleName.empty()) {
475 HILOG_ERROR("bundleName is empty.");
476 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
477 }
478
479 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
480 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
481 }
482
483 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
484 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
485 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
486 HILOG_ERROR("no forms found.");
487 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
488 }
489
490 if (bundleFormInfoIter->second != nullptr) {
491 bundleFormInfoIter->second->GetAllFormsInfo(formInfos);
492 }
493 return ERR_OK;
494 }
495
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos)496 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
497 std::vector<FormInfo> &formInfos)
498 {
499 if (bundleName.empty()) {
500 HILOG_ERROR("bundleName is empty.");
501 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
502 }
503
504 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
505 HILOG_ERROR("CheckBundlePermission and IsCaller failed.");
506 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
507 }
508
509 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
510 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
511 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
512 HILOG_ERROR("no forms found for %{public}s.", bundleName.c_str());
513 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
514 }
515
516 if (bundleFormInfoIter->second != nullptr) {
517 bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos);
518 }
519 return ERR_OK;
520 }
521
CheckDynamicFormInfo(FormInfo & formInfo,const BundleInfo & bundleInfo)522 ErrCode FormInfoMgr::CheckDynamicFormInfo(FormInfo &formInfo, const BundleInfo &bundleInfo)
523 {
524 for (auto &moduleInfo : bundleInfo.hapModuleInfos) {
525 if (formInfo.moduleName != moduleInfo.moduleName) {
526 continue;
527 }
528 for (auto &abilityInfo : moduleInfo.abilityInfos) {
529 if (formInfo.abilityName != abilityInfo.name) {
530 continue;
531 }
532 formInfo.src = "";
533 return ERR_OK;
534 }
535 for (auto &extensionInfos : moduleInfo.extensionInfos) {
536 if (formInfo.abilityName != extensionInfos.name) {
537 continue;
538 }
539 formInfo.src = "./js/" + formInfo.name + "/pages/index/index";
540 return ERR_OK;
541 }
542 HILOG_ERROR("No match abilityName found");
543 return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY;
544 }
545
546 HILOG_ERROR("No match moduleName found");
547 return ERR_APPEXECFWK_FORM_NO_SUCH_MODULE;
548 }
549
AddDynamicFormInfo(FormInfo & formInfo,int32_t userId)550 ErrCode FormInfoMgr::AddDynamicFormInfo(FormInfo &formInfo, int32_t userId)
551 {
552 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
553 if (iBundleMgr == nullptr) {
554 HILOG_ERROR("failed to get IBundleMgr.");
555 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
556 }
557
558 BundleInfo bundleInfo;
559 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
560 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(formInfo.bundleName, flag, bundleInfo, userId))) {
561 HILOG_ERROR("failed to get bundle info.");
562 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
563 }
564
565 ErrCode errCode = CheckDynamicFormInfo(formInfo, bundleInfo);
566 if (errCode != ERR_OK) {
567 HILOG_ERROR("failed to CheckDynamicFormInfo.");
568 return errCode;
569 }
570
571 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
572 auto bundleFormInfoIter = bundleFormInfoMap_.find(formInfo.bundleName);
573 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
574 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
575 bundleFormInfoPtr = bundleFormInfoIter->second;
576 } else {
577 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(formInfo.bundleName);
578 }
579
580 return bundleFormInfoPtr->AddDynamicFormInfo(formInfo, userId);
581 }
582
RemoveDynamicFormInfo(const std::string & bundleName,const std::string & moduleName,const std::string & formName,int32_t userId)583 ErrCode FormInfoMgr::RemoveDynamicFormInfo(const std::string &bundleName, const std::string &moduleName,
584 const std::string &formName, int32_t userId)
585 {
586 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
587 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
588 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
589 HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
590 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
591 }
592
593 return bundleFormInfoIter->second->RemoveDynamicFormInfo(moduleName, formName, userId);
594 }
595
RemoveAllDynamicFormsInfo(const std::string & bundleName,int32_t userId)596 ErrCode FormInfoMgr::RemoveAllDynamicFormsInfo(const std::string &bundleName, int32_t userId)
597 {
598 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
599 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
600 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
601 HILOG_ERROR("no forms found in bundle %{public}s.", bundleName.c_str());
602 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
603 }
604
605 return bundleFormInfoIter->second->RemoveAllDynamicFormsInfo(userId);
606 }
607
GetOrCreateBundleFromInfo(const std::string & bundleName)608 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
609 {
610 {
611 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
612 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
613 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
614 // found
615 return bundleFormInfoIter->second;
616 }
617 }
618
619 // not found
620 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
621 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
622 // try to find again
623 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
624 // found
625 return bundleFormInfoIter->second;
626 }
627 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
628 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
629 return bundleFormInfoPtr;
630 }
631
IsCaller(const std::string & bundleName)632 bool FormInfoMgr::IsCaller(const std::string& bundleName)
633 {
634 auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
635 if (bms == nullptr) {
636 HILOG_ERROR("Failed to get Bundle Mgr.");
637 return false;
638 }
639 AppExecFwk::BundleInfo bundleInfo;
640 bool ret = IN_PROCESS_CALL(
641 bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
642 if (!ret) {
643 HILOG_ERROR("Failed to get bundle info.");
644 return false;
645 }
646 auto callerToken = IPCSkeleton::GetCallingTokenID();
647 if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
648 return true;
649 }
650 return false;
651 }
652
CheckBundlePermission()653 bool FormInfoMgr::CheckBundlePermission()
654 {
655 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
656 if (isSaCall) {
657 return true;
658 }
659 auto isCallingPerm = AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
660 AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
661 if (isCallingPerm) {
662 return true;
663 }
664 HILOG_ERROR("Permission verification failed");
665 return false;
666 }
667
ReloadFormInfos(const int32_t userId)668 ErrCode FormInfoMgr::ReloadFormInfos(const int32_t userId)
669 {
670 HILOG_INFO("ReloadFormInfos userId: %{public}d.", userId);
671 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
672 if (iBundleMgr == nullptr) {
673 HILOG_ERROR("failed to get IBundleMgr.");
674 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
675 }
676
677 std::vector<ApplicationInfo> appInfos {};
678 if (!IN_PROCESS_CALL(iBundleMgr->GetApplicationInfos(GET_BASIC_APPLICATION_INFO, userId, appInfos))) {
679 HILOG_ERROR("failed to get Application info.");
680 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
681 }
682
683 std::set<std::string> bundleNameSet {};
684 for (auto const &appInfo : appInfos) {
685 bundleNameSet.emplace(appInfo.bundleName);
686 }
687
688 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
689 for (auto const &bundleFormInfoPair : bundleFormInfoMap_) {
690 const std::string &bundleName = bundleFormInfoPair.first;
691 auto setFindIter = bundleNameSet.find(bundleName);
692 if (setFindIter == bundleNameSet.end()) {
693 bundleFormInfoPair.second->Remove(userId);
694 HILOG_INFO("remove forms info success, bundleName=%{public}s", bundleName.c_str());
695 continue;
696 }
697 bundleNameSet.erase(setFindIter);
698 bundleFormInfoPair.second->UpdateStaticFormInfos(userId);
699 HILOG_INFO("update forms info success, bundleName=%{public}s", bundleName.c_str());
700 }
701
702 for (auto const &bundleName : bundleNameSet) {
703 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
704 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
705 if (errCode != ERR_OK || bundleFormInfoPtr->Empty()) {
706 continue;
707 }
708 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
709 HILOG_INFO("add forms info success, bundleName=%{public}s", bundleName.c_str());
710 }
711 return ERR_OK;
712 }
713 } // namespace AppExecFwk
714 } // namespace OHOS
715