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