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_db_cache.h"
23 #include "form_info_storage.h"
24 #include "form_info_rdb_storage_mgr.h"
25 #include "form_mgr_errors.h"
26 #include "form_util.h"
27 #include "hitrace_meter.h"
28 #include "in_process_call_wrapper.h"
29 #include "ipc_skeleton.h"
30 #include "json_serializer.h"
31 #include "permission_verification.h"
32 #include "form_event_report.h"
33
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 const std::string FORM_METADATA_NAME = "ohos.extension.form";
38 const std::uint32_t ERR_VERSION_CODE = 0;
39 } // namespace
40
LoadFormConfigInfoByBundleName(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)41 ErrCode FormInfoHelper::LoadFormConfigInfoByBundleName(const std::string &bundleName, std::vector<FormInfo> &formInfos,
42 int32_t userId)
43 {
44 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
45 if (bundleName.empty()) {
46 HILOG_ERROR("invalid bundleName");
47 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
48 }
49
50 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
51 if (iBundleMgr == nullptr) {
52 HILOG_ERROR("get IBundleMgr failed");
53 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
54 }
55
56 BundleInfo bundleInfo;
57 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
58 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(bundleName, flag, bundleInfo, userId))) {
59 HILOG_ERROR("get bundleInfo failed");
60 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
61 }
62 if (bundleInfo.abilityInfos.empty()) {
63 HILOG_WARN("empty abilityInfos");
64 // Check if current bundle contains FA forms.
65 LoadAbilityFormConfigInfo(bundleInfo, formInfos);
66 // Check if current bundle contains Stage forms.
67 LoadStageFormConfigInfo(bundleInfo, formInfos);
68 return ERR_OK;
69 }
70 if (bundleInfo.abilityInfos[0].isStageBasedModel) {
71 LoadStageFormConfigInfo(bundleInfo, formInfos);
72 } else {
73 LoadAbilityFormConfigInfo(bundleInfo, formInfos);
74 }
75 return ERR_OK;
76 }
77
LoadStageFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)78 ErrCode FormInfoHelper::LoadStageFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
79 {
80 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
81 std::shared_ptr<BundleMgrClient> client = DelayedSingleton<BundleMgrClient>::GetInstance();
82 if (client == nullptr) {
83 HILOG_ERROR("fail get BundleMgrClient");
84 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
85 }
86 for (auto const &extensionInfo: bundleInfo.extensionInfos) {
87 if (extensionInfo.type != ExtensionAbilityType::FORM) {
88 continue;
89 }
90 std::vector<std::string> profileInfos {};
91 if (!client->GetResConfigFile(extensionInfo, FORM_METADATA_NAME, profileInfos)) {
92 HILOG_ERROR("fail get form metadata");
93 continue;
94 }
95 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("fail 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 formInfo.versionCode = bundleInfo.versionCode;
109 formInfo.bundleType = bundleInfo.applicationInfo.bundleType;
110 formInfo.privacyLevel = privacyLevel;
111 HILOG_INFO("LoadStageFormConfigInfo, bundleName: %{public}s, name: %{public}s, "
112 "renderingMode: %{public}d",
113 formInfo.bundleName.c_str(), formInfo.name.c_str(), static_cast<int>(formInfo.renderingMode));
114 NewFormEventInfo eventInfo;
115 eventInfo.bundleName = formInfo.bundleName;
116 eventInfo.formName = formInfo.name;
117 eventInfo.renderingMode = static_cast<int32_t>(formInfo.renderingMode);
118 FormEventReport::SendLoadStageFormConfigInfoEvent(FormEventName::LOAD_STAGE_FORM_CONFIG_INFO,
119 HiSysEventType::BEHAVIOR, eventInfo);
120 formInfos.emplace_back(formInfo);
121 }
122 }
123 }
124 return ERR_OK;
125 }
126
LoadAbilityFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)127 ErrCode FormInfoHelper::LoadAbilityFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
128 {
129 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
130 if (iBundleMgr == nullptr) {
131 HILOG_ERROR("get IBundleMgr failed");
132 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
133 }
134 const std::string &bundleName = bundleInfo.name;
135 for (const auto &moduleInfo: bundleInfo.hapModuleInfos) {
136 const std::string &moduleName = moduleInfo.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 formInfo.versionCode = bundleInfo.versionCode;
143 formInfo.bundleType = bundleInfo.applicationInfo.bundleType;
144 formInfos.emplace_back(formInfo);
145 }
146 }
147 return ERR_OK;
148 }
GetResourceManager(const BundleInfo & bundleInfo)149 std::shared_ptr<Global::Resource::ResourceManager> FormInfoHelper::GetResourceManager(const BundleInfo &bundleInfo)
150 {
151 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
152 HILOG_INFO("bundleInfoName:%{public}s", bundleInfo.name.c_str());
153 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
154 if (resourceManager == nullptr) {
155 HILOG_ERROR("InitResourceManager failed");
156 return nullptr;
157 }
158 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
159 std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
160 if (!moduleResPath.empty()) {
161 HILOG_DEBUG("DistributedBms::InitResourceManager, moduleResPath: %{private}s", moduleResPath.c_str());
162 if (!resourceManager->AddResource(moduleResPath.c_str())) {
163 HILOG_ERROR("DistributedBms::InitResourceManager AddResource failed");
164 }
165 }
166 }
167 return resourceManager;
168 }
169
GetFormInfoDisplayName(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,FormInfo & formInfo)170 ErrCode FormInfoHelper::GetFormInfoDisplayName(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager,
171 FormInfo &formInfo)
172 {
173 if (formInfo.displayNameId != 0) {
174 std::string displayName;
175 auto state = resourceManager->GetStringById(static_cast<uint32_t>(formInfo.displayNameId), displayName);
176 if (state != OHOS::Global::Resource::RState::SUCCESS) {
177 HILOG_ERROR("ResourceManager GetStringById with displayNameId failed");
178 return ERR_APPEXECFWK_FORM_COMMON_CODE;
179 }
180 formInfo.displayName = displayName;
181 }
182 return ERR_OK;
183 }
184
GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> & resourceManager,FormInfo & formInfo)185 ErrCode FormInfoHelper::GetFormInfoDescription(std::shared_ptr<Global::Resource::ResourceManager> &resourceManager,
186 FormInfo &formInfo)
187 {
188 if (formInfo.descriptionId != 0) {
189 std::string description;
190 auto state = resourceManager->GetStringById(static_cast<uint32_t>(formInfo.descriptionId), description);
191 if (state != OHOS::Global::Resource::RState::SUCCESS) {
192 HILOG_ERROR("ResourceManager GetStringById failed");
193 return ERR_APPEXECFWK_FORM_COMMON_CODE;
194 }
195 formInfo.description = description;
196 }
197 return ERR_OK;
198 }
199
BundleFormInfo(const std::string & bundleName)200 BundleFormInfo::BundleFormInfo(const std::string &bundleName) : bundleName_(bundleName)
201 {
202 }
203
InitFromJson(const std::string & formInfoStoragesJson)204 ErrCode BundleFormInfo::InitFromJson(const std::string &formInfoStoragesJson)
205 {
206 nlohmann::json jsonObject = nlohmann::json::parse(formInfoStoragesJson, nullptr, false);
207 if (jsonObject.is_discarded() || !jsonObject.is_array()) {
208 HILOG_ERROR("bad profile");
209 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
210 }
211 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
212 auto formInfoStorages = jsonObject.get<std::vector<AAFwk::FormInfoStorage>>();
213 for (const auto &item : formInfoStorages) {
214 formInfoStorages_.push_back(item);
215 }
216 return ERR_OK;
217 }
218
UpdateStaticFormInfos(int32_t userId)219 ErrCode BundleFormInfo::UpdateStaticFormInfos(int32_t userId)
220 {
221 HILOG_DEBUG("Update static form infos, userId is %{public}d", userId);
222 std::vector<FormInfo> formInfos;
223 ErrCode errCode = FormInfoHelper::LoadFormConfigInfoByBundleName(bundleName_, formInfos, userId);
224 if (errCode != ERR_OK) {
225 HILOG_ERROR("LoadFormConfigInfoByBundleName failed, errCode:%{public}d", errCode);
226 return errCode;
227 }
228
229 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
230 if (!formInfos.empty()) {
231 std::vector<FormDBInfo> formDBInfos;
232 std::vector<FormInfo> finalFormInfos;
233 FormDbCache::GetInstance().GetAllFormDBInfoByBundleName(bundleName_, userId, formDBInfos);
234 HandleFormInfosMaxLimit(formInfos, finalFormInfos, formDBInfos);
235 bool findUser = false;
236 for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end(); ++item) {
237 // Update all user's formInfos
238 HILOG_DEBUG("Update formInfos, user:%{public}d", item->userId);
239 item->formInfos = finalFormInfos;
240 findUser = findUser || (item->userId == userId);
241 }
242 if (!findUser) {
243 HILOG_DEBUG("Add new userId, user:%{public}d", userId);
244 formInfoStorages_.emplace_back(userId, finalFormInfos);
245 }
246 } else {
247 HILOG_DEBUG("The new package of %{public}s does not contain a card, clear it", bundleName_.c_str());
248 formInfoStorages_.clear();
249 }
250
251 return UpdateFormInfoStorageLocked();
252 }
253
Remove(int32_t userId)254 ErrCode BundleFormInfo::Remove(int32_t userId)
255 {
256 HILOG_INFO("userId is %{public}d", userId);
257 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
258 for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
259 if (item->userId == userId) {
260 item = formInfoStorages_.erase(item);
261 } else {
262 ++item;
263 }
264 }
265 return UpdateFormInfoStorageLocked();
266 }
267
AddDynamicFormInfo(const FormInfo & formInfo,int32_t userId)268 ErrCode BundleFormInfo::AddDynamicFormInfo(const FormInfo &formInfo, int32_t userId)
269 {
270 HILOG_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 bool isSame = false;
277 for (const auto &item : formInfoStorage.formInfos) {
278 if (item.name == formInfo.name && item.moduleName == formInfo.moduleName) {
279 isSame = true;
280 break;
281 }
282 }
283
284 if (isSame) {
285 HILOG_ERROR("The same form already exists");
286 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
287 }
288 formInfoStorage.formInfos.push_back(formInfo);
289 return UpdateFormInfoStorageLocked();
290 }
291 // no match user id
292 std::vector<FormInfo> formInfos;
293 formInfos.push_back(formInfo);
294 formInfoStorages_.emplace_back(userId, formInfos);
295 return UpdateFormInfoStorageLocked();
296 }
297
RemoveDynamicFormInfo(const std::string & moduleName,const std::string & formName,int32_t userId)298 ErrCode BundleFormInfo::RemoveDynamicFormInfo(const std::string &moduleName, const std::string &formName,
299 int32_t userId)
300 {
301 HILOG_INFO("userId is %{public}d", userId);
302 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
303 for (auto &formInfoStorage : formInfoStorages_) {
304 if (formInfoStorage.userId != userId) {
305 continue;
306 }
307 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
308 if (item->name != formName || item->moduleName != moduleName) {
309 ++item;
310 continue;
311 }
312 // form found
313 if (item->isStatic) {
314 HILOG_ERROR("the specifiedFormInfo is static,can't be removed");
315 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
316 }
317 item = formInfoStorage.formInfos.erase(item);
318 return UpdateFormInfoStorageLocked();
319 }
320 }
321 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
322 }
323
RemoveAllDynamicFormsInfo(int32_t userId)324 ErrCode BundleFormInfo::RemoveAllDynamicFormsInfo(int32_t userId)
325 {
326 HILOG_INFO("userId is %{public}d", userId);
327 std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
328 int32_t numRemoved = 0;
329 for (auto &formInfoStorage : formInfoStorages_) {
330 if (formInfoStorage.userId != userId) {
331 continue;
332 }
333 for (auto item = formInfoStorage.formInfos.begin(); item != formInfoStorage.formInfos.end();) {
334 if (!item->isStatic) {
335 ++numRemoved;
336 item = formInfoStorage.formInfos.erase(item);
337 } else {
338 ++item;
339 }
340 }
341 break;
342 }
343 if (numRemoved > 0) {
344 HILOG_ERROR("%{public}d dynamic forms info removed.", numRemoved);
345 return UpdateFormInfoStorageLocked();
346 }
347 return ERR_OK;
348 }
349
Empty() const350 bool BundleFormInfo::Empty() const
351 {
352 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
353 return formInfoStorages_.empty();
354 }
355
GetAllFormsInfo(std::vector<FormInfo> & formInfos,int32_t userId)356 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos, int32_t userId)
357 {
358 HILOG_DEBUG("begin");
359 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
360 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
361 for (const auto &item : formInfoStorages_) {
362 item.GetAllFormsInfo(userId, formInfos);
363 }
364 return ERR_OK;
365 }
366
GetVersionCode(int32_t userId)367 uint32_t BundleFormInfo::GetVersionCode(int32_t userId)
368 {
369 HILOG_DEBUG("begin");
370 std::vector<FormInfo> formInfos;
371 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
372 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
373 for (const auto &item : formInfoStorages_) {
374 item.GetAllFormsInfo(userId, formInfos);
375 for (const auto &info : formInfos) {
376 if (info.versionCode != ERR_VERSION_CODE) {
377 return info.versionCode;
378 }
379 }
380 }
381 return ERR_VERSION_CODE;
382 }
383
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)384 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos,
385 int32_t userId)
386 {
387 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
388 userId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
389 for (const auto &item : formInfoStorages_) {
390 item.GetFormsInfoByModule(userId, moduleName, formInfos);
391 }
392 return ERR_OK;
393 }
394
GetFormsInfoByFilter(const FormInfoFilter & filter,std::vector<FormInfo> & formInfos,int32_t userId)395 ErrCode BundleFormInfo::GetFormsInfoByFilter(
396 const FormInfoFilter &filter, std::vector<FormInfo> &formInfos, int32_t userId)
397 {
398 HILOG_DEBUG("begin");
399 std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
400 auto newUserId = (userId == Constants::INVALID_USER_ID) ? FormUtil::GetCurrentAccountId() : userId;
401
402 for (const auto &item : formInfoStorages_) {
403 item.GetFormsInfoByFilter(newUserId, filter, formInfos);
404 }
405 return ERR_OK;
406 }
407
UpdateFormInfoStorageLocked()408 ErrCode BundleFormInfo::UpdateFormInfoStorageLocked()
409 {
410 ErrCode errCode;
411 if (formInfoStorages_.empty()) {
412 errCode = FormInfoRdbStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
413 } else {
414 nlohmann::json jsonObject = formInfoStorages_;
415 if (jsonObject.is_discarded()) {
416 HILOG_ERROR("bad form infos");
417 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
418 }
419 std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
420 errCode = FormInfoRdbStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
421 }
422 return errCode;
423 }
424
HandleFormInfosMaxLimit(std::vector<FormInfo> & inFormInfos,std::vector<FormInfo> & outFormInfos,const std::vector<FormDBInfo> & formDBInfos)425 void BundleFormInfo::HandleFormInfosMaxLimit(std::vector<FormInfo> &inFormInfos,
426 std::vector<FormInfo> &outFormInfos, const std::vector<FormDBInfo> &formDBInfos)
427 {
428 HILOG_INFO("formInfo num: %{public}u,formDBInfo num: %{public}u", inFormInfos.size(), formDBInfos.size());
429 std::set<std::string> formDBNames;
430 GetAllUsedFormName(formDBInfos, inFormInfos, formDBNames);
431 if (formDBNames.empty() || inFormInfos.size() <= Constants::FORM_INFO_MAX_NUM) {
432 if (inFormInfos.size() > Constants::FORM_INFO_MAX_NUM) {
433 unsigned int needPopNum = inFormInfos.size() - Constants::FORM_INFO_MAX_NUM;
434 for (unsigned int i = 0; i < needPopNum; i++) {
435 inFormInfos.pop_back();
436 }
437 }
438 outFormInfos = inFormInfos;
439 return;
440 }
441 int addFormNum = 0;
442 unsigned int formNum = formDBNames.size();
443 if (formDBNames.size() < Constants::FORM_INFO_MAX_NUM) {
444 addFormNum = Constants::FORM_INFO_MAX_NUM - formDBNames.size();
445 formNum = Constants::FORM_INFO_MAX_NUM;
446 }
447 for (auto formInfo : inFormInfos) {
448 bool isUsed = formDBNames.find(formInfo.name) != formDBNames.end();
449 if (isUsed) {
450 outFormInfos.push_back(formInfo);
451 } else if (!isUsed && addFormNum > 0) {
452 outFormInfos.push_back(formInfo);
453 addFormNum--;
454 }
455 if (outFormInfos.size() == formNum) {
456 break;
457 }
458 }
459 }
460
GetAllUsedFormName(const std::vector<FormDBInfo> & formDBInfos,const std::vector<FormInfo> & formInfos,std::set<std::string> & formDBNames)461 void BundleFormInfo::GetAllUsedFormName(const std::vector<FormDBInfo> &formDBInfos,
462 const std::vector<FormInfo> &formInfos, std::set<std::string> &formDBNames)
463 {
464 if (formDBInfos.empty() || formInfos.empty()) {
465 return;
466 }
467 for (auto formDBInfo : formDBInfos) {
468 if (formDBNames.count(formDBInfo.formName) > 0) {
469 continue;
470 }
471 for (auto formInfo : formInfos) {
472 if (formInfo.name == formDBInfo.formName) {
473 formDBNames.insert(formDBInfo.formName);
474 break;
475 }
476 }
477 }
478 HILOG_INFO("used form num: %{public}u", formDBNames.size());
479 }
480
FormInfoMgr()481 FormInfoMgr::FormInfoMgr()
482 {
483 HILOG_INFO("create");
484 }
485
486 FormInfoMgr::~FormInfoMgr() = default;
487
Start()488 ErrCode FormInfoMgr::Start()
489 {
490 std::vector<std::pair<std::string, std::string>> formInfoStorages;
491 ErrCode errCode = FormInfoRdbStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
492 if (errCode != ERR_OK) {
493 HILOG_ERROR("LoadFormInfos failed");
494 return errCode;
495 }
496
497 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
498 for (const auto &item: formInfoStorages) {
499 const std::string &bundleName = item.first;
500 const std::string &formInfoStoragesJson = item.second;
501 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
502 errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
503 if (errCode != ERR_OK) {
504 continue;
505 }
506 HILOG_INFO("load bundle %{public}s form infos success.", bundleName.c_str());
507 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
508 }
509 HILOG_INFO("load bundle form infos from db done");
510 return ERR_OK;
511 }
512
UpdateStaticFormInfos(const std::string & bundleName,int32_t userId)513 ErrCode FormInfoMgr::UpdateStaticFormInfos(const std::string &bundleName, int32_t userId)
514 {
515 if (bundleName.empty()) {
516 HILOG_ERROR("empty bundleName");
517 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
518 }
519
520 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
521 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
522 auto search = bundleFormInfoMap_.find(bundleName);
523 if (search != bundleFormInfoMap_.end()) {
524 bundleFormInfoPtr = search->second;
525 } else {
526 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
527 }
528
529 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
530 if (errCode != ERR_OK) {
531 return errCode;
532 }
533
534 if (bundleFormInfoPtr->Empty()) {
535 // no forms found, no need to be inserted into the map
536 return ERR_OK;
537 }
538
539 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
540 HILOG_INFO("success, bundleName=%{public}s", bundleName.c_str());
541 return ERR_OK;
542 }
543
Remove(const std::string & bundleName,int32_t userId)544 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
545 {
546 if (bundleName.empty()) {
547 HILOG_ERROR("empty bundleName");
548 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
549 }
550
551 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
552 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
553 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
554 // BundleFormInfo not found, no need to remove
555 return ERR_OK;
556 }
557
558 ErrCode errCode = ERR_OK;
559 if (bundleFormInfoIter->second != nullptr) {
560 errCode = bundleFormInfoIter->second->Remove(userId);
561 }
562
563 if (bundleFormInfoIter->second && bundleFormInfoIter->second->Empty()) {
564 bundleFormInfoMap_.erase(bundleFormInfoIter);
565 }
566 HILOG_INFO("success, bundleName=%{public}s", bundleName.c_str());
567 return errCode;
568 }
569
GetAllFormsInfo(std::vector<FormInfo> & formInfos)570 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
571 {
572 if (!CheckBundlePermission()) {
573 HILOG_ERROR("CheckBundlePermission is failed");
574 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
575 }
576 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
577 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
578 if (bundleFormInfo.second != nullptr) {
579 bundleFormInfo.second->GetAllFormsInfo(formInfos);
580 }
581 }
582 return ERR_OK;
583 }
584
GetFormsInfoByFilter(const FormInfoFilter & filter,std::vector<FormInfo> & formInfos,int32_t userId)585 ErrCode FormInfoMgr::GetFormsInfoByFilter(
586 const FormInfoFilter &filter, std::vector<FormInfo> &formInfos, int32_t userId)
587 {
588 if (!CheckBundlePermission()) {
589 if (filter.bundleName.empty() || !IsCaller(filter.bundleName)) {
590 HILOG_ERROR("Permission is wrong");
591 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
592 }
593 }
594 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
595 if (filter.bundleName.empty()) {
596 for (const auto &bundleFormInfo : bundleFormInfoMap_) {
597 if (bundleFormInfo.second != nullptr) {
598 bundleFormInfo.second->GetFormsInfoByFilter(filter, formInfos, userId);
599 }
600 }
601 } else {
602 auto bundleFormInfoIter = bundleFormInfoMap_.find(filter.bundleName);
603 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
604 HILOG_WARN("no forms found for bundle name:%{public}s", filter.bundleName.c_str());
605 return ERR_OK;
606 }
607 if (bundleFormInfoIter->second != nullptr) {
608 bundleFormInfoIter->second->GetFormsInfoByFilter(filter, formInfos, userId);
609 }
610 }
611 return ERR_OK;
612 }
613
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos,int32_t userId)614 ErrCode FormInfoMgr::GetFormsInfoByBundle(
615 const std::string &bundleName, std::vector<FormInfo> &formInfos, int32_t userId)
616 {
617 if (bundleName.empty()) {
618 HILOG_ERROR("empty bundleName");
619 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
620 }
621
622 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
623 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
624 }
625
626 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
627 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
628 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
629 HILOG_ERROR("no forms found");
630 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
631 }
632
633 if (bundleFormInfoIter->second != nullptr) {
634 bundleFormInfoIter->second->GetAllFormsInfo(formInfos, userId);
635 }
636 return ERR_OK;
637 }
638
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)639 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
640 std::vector<FormInfo> &formInfos, int32_t userId)
641 {
642 if (bundleName.empty()) {
643 HILOG_ERROR("empty bundleName");
644 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
645 }
646
647 if (!CheckBundlePermission() && !IsCaller(bundleName)) {
648 HILOG_ERROR("CheckBundlePermission and IsCaller failed");
649 return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
650 }
651
652 return GetFormsInfoByModuleWithoutCheck(bundleName, moduleName, formInfos, userId);
653 }
654
GetFormsInfoByModuleWithoutCheck(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos,int32_t userId)655 ErrCode FormInfoMgr::GetFormsInfoByModuleWithoutCheck(const std::string &bundleName, const std::string &moduleName,
656 std::vector<FormInfo> &formInfos, int32_t userId)
657 {
658 if (bundleName.empty()) {
659 HILOG_ERROR("empty bundleName");
660 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
661 }
662
663 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
664 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
665 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
666 HILOG_ERROR("no forms found for %{public}s", bundleName.c_str());
667 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
668 }
669
670 if (bundleFormInfoIter->second != nullptr) {
671 bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos, userId);
672 }
673 return ERR_OK;
674 }
675
GetFormsInfoByRecord(const FormRecord & formRecord,FormInfo & formInfo)676 ErrCode FormInfoMgr::GetFormsInfoByRecord(const FormRecord &formRecord, FormInfo &formInfo)
677 {
678 std::vector<FormInfo> formInfos;
679 {
680 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
681 auto bundleFormInfoIter = bundleFormInfoMap_.find(formRecord.bundleName);
682 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
683 HILOG_ERROR("no forms found for %{public}s", formRecord.bundleName.c_str());
684 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
685 }
686
687 if (bundleFormInfoIter->second == nullptr) {
688 HILOG_ERROR("null BundleFormInfo");
689 return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
690 }
691
692 bundleFormInfoIter->second->GetFormsInfoByModule(formRecord.moduleName, formInfos);
693 }
694 for (const FormInfo &info : formInfos) {
695 if (info.name == formRecord.formName) {
696 formInfo = info;
697 break;
698 }
699 }
700 return formInfo.name.empty() ? ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED : ERR_OK;
701 }
702
CheckDynamicFormInfo(FormInfo & formInfo,const BundleInfo & bundleInfo)703 ErrCode FormInfoMgr::CheckDynamicFormInfo(FormInfo &formInfo, const BundleInfo &bundleInfo)
704 {
705 for (auto &moduleInfo : bundleInfo.hapModuleInfos) {
706 if (formInfo.moduleName != moduleInfo.moduleName) {
707 continue;
708 }
709 for (auto &abilityInfo : moduleInfo.abilityInfos) {
710 if (formInfo.abilityName != abilityInfo.name) {
711 continue;
712 }
713 formInfo.src = "";
714 return ERR_OK;
715 }
716 for (auto &extensionInfos : moduleInfo.extensionInfos) {
717 if (formInfo.abilityName != extensionInfos.name) {
718 continue;
719 }
720 formInfo.src = "./js/" + formInfo.name + "/pages/index/index";
721 return ERR_OK;
722 }
723 HILOG_ERROR("No match abilityName found");
724 return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY;
725 }
726
727 HILOG_ERROR("No match moduleName found");
728 return ERR_APPEXECFWK_FORM_NO_SUCH_MODULE;
729 }
730
AddDynamicFormInfo(FormInfo & formInfo,int32_t userId)731 ErrCode FormInfoMgr::AddDynamicFormInfo(FormInfo &formInfo, int32_t userId)
732 {
733 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
734 if (iBundleMgr == nullptr) {
735 HILOG_ERROR("get IBundleMgr failed");
736 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
737 }
738
739 BundleInfo bundleInfo;
740 int32_t flag = GET_BUNDLE_WITH_EXTENSION_INFO | GET_BUNDLE_WITH_ABILITIES;
741 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(formInfo.bundleName, flag, bundleInfo, userId))) {
742 HILOG_ERROR("get bundleInfo failed");
743 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
744 }
745
746 ErrCode errCode = CheckDynamicFormInfo(formInfo, bundleInfo);
747 if (errCode != ERR_OK) {
748 HILOG_ERROR("fail CheckDynamicFormInfo");
749 return errCode;
750 }
751
752 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
753 auto bundleFormInfoIter = bundleFormInfoMap_.find(formInfo.bundleName);
754 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
755 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
756 bundleFormInfoPtr = bundleFormInfoIter->second;
757 } else {
758 bundleFormInfoPtr = std::make_shared<BundleFormInfo>(formInfo.bundleName);
759 }
760
761 return bundleFormInfoPtr->AddDynamicFormInfo(formInfo, userId);
762 }
763
RemoveDynamicFormInfo(const std::string & bundleName,const std::string & moduleName,const std::string & formName,int32_t userId)764 ErrCode FormInfoMgr::RemoveDynamicFormInfo(const std::string &bundleName, const std::string &moduleName,
765 const std::string &formName, int32_t userId)
766 {
767 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
768 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
769 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
770 HILOG_ERROR("no forms found in bundle %{public}s", bundleName.c_str());
771 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
772 }
773
774 return bundleFormInfoIter->second->RemoveDynamicFormInfo(moduleName, formName, userId);
775 }
776
RemoveAllDynamicFormsInfo(const std::string & bundleName,int32_t userId)777 ErrCode FormInfoMgr::RemoveAllDynamicFormsInfo(const std::string &bundleName, int32_t userId)
778 {
779 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
780 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
781 if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
782 HILOG_ERROR("no forms found in bundle %{public}s", bundleName.c_str());
783 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
784 }
785
786 return bundleFormInfoIter->second->RemoveAllDynamicFormsInfo(userId);
787 }
788
GetOrCreateBundleFromInfo(const std::string & bundleName)789 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
790 {
791 {
792 std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
793 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
794 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
795 // found
796 return bundleFormInfoIter->second;
797 }
798 }
799
800 // not found
801 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
802 auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
803 // try to find again
804 if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
805 // found
806 return bundleFormInfoIter->second;
807 }
808 auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
809 bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
810 return bundleFormInfoPtr;
811 }
812
IsCaller(const std::string & bundleName)813 bool FormInfoMgr::IsCaller(const std::string& bundleName)
814 {
815 auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
816 if (bms == nullptr) {
817 HILOG_ERROR("fail get Bundle Mgr");
818 return false;
819 }
820 AppExecFwk::BundleInfo bundleInfo;
821 bool ret = IN_PROCESS_CALL(
822 bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
823 if (!ret) {
824 HILOG_ERROR("get bundleInfo failed");
825 return false;
826 }
827 auto callerToken = IPCSkeleton::GetCallingTokenID();
828 if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
829 return true;
830 }
831 return false;
832 }
833
CheckBundlePermission()834 bool FormInfoMgr::CheckBundlePermission()
835 {
836 if (FormUtil::IsSACall()) {
837 return true;
838 }
839 if (FormUtil::VerifyCallingPermission(AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
840 return true;
841 }
842 HILOG_ERROR("Permission verification failed");
843 return false;
844 }
845
ReloadFormInfos(const int32_t userId)846 ErrCode FormInfoMgr::ReloadFormInfos(const int32_t userId)
847 {
848 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
849 HILOG_INFO("userId:%{public}d", userId);
850 std::map<std::string, std::uint32_t> bundleVersionMap {};
851 ErrCode result = GetBundleVersionMap(bundleVersionMap, userId);
852 if (result != ERR_OK) {
853 return result;
854 }
855 std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
856 hasReloadedFormInfosState_ = false;
857 UpdateBundleFormInfos(bundleVersionMap, userId);
858 for (auto const &bundleVersionPair : bundleVersionMap) {
859 std::shared_ptr<BundleFormInfo> bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleVersionPair.first);
860 ErrCode errCode = bundleFormInfoPtr->UpdateStaticFormInfos(userId);
861 if (errCode != ERR_OK || bundleFormInfoPtr->Empty()) {
862 continue;
863 }
864 bundleFormInfoMap_[bundleVersionPair.first] = bundleFormInfoPtr;
865 HILOG_INFO("add forms info success, bundleName=%{public}s, versionCode:%{public}d",
866 bundleVersionPair.first.c_str(), bundleVersionPair.second);
867 }
868 hasReloadedFormInfosState_ = true;
869 HILOG_INFO("end, formInfoMapSize:%{public}zu", bundleFormInfoMap_.size());
870 return ERR_OK;
871 }
872
HasReloadedFormInfos()873 bool FormInfoMgr::HasReloadedFormInfos()
874 {
875 HILOG_DEBUG("Reloaded Form Infos state %{public}d", hasReloadedFormInfosState_);
876 return hasReloadedFormInfosState_;
877 }
878
GetBundleVersionMap(std::map<std::string,std::uint32_t> & bundleVersionMap,int32_t userId)879 ErrCode FormInfoMgr::GetBundleVersionMap(std::map<std::string, std::uint32_t> &bundleVersionMap, int32_t userId)
880 {
881 sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
882 if (iBundleMgr == nullptr) {
883 HILOG_ERROR("get IBundleMgr failed");
884 return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
885 }
886
887 std::vector<ExtensionAbilityInfo> extensionInfos {};
888 if (!IN_PROCESS_CALL(iBundleMgr->QueryExtensionAbilityInfos(ExtensionAbilityType::FORM, userId, extensionInfos))) {
889 HILOG_ERROR("get extension infos failed");
890 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
891 }
892
893 std::vector<BundleInfo> bundleInfos {};
894 if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfos(GET_BUNDLE_WITH_ABILITIES, bundleInfos, userId))) {
895 HILOG_ERROR("get bundle infos failed");
896 return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
897 }
898
899 // get names of bundles that must contain stage forms
900 for (auto const &extensionInfo : extensionInfos) {
901 bundleVersionMap.insert(std::make_pair(extensionInfo.bundleName, extensionInfo.applicationInfo.versionCode));
902 }
903 // get names of bundles that may contain fa forms
904 for (auto const &bundleInfo : bundleInfos) {
905 if (!bundleInfo.abilityInfos.empty() && !bundleInfo.abilityInfos[0].isStageBasedModel) {
906 bundleVersionMap.insert(std::make_pair(bundleInfo.name, bundleInfo.versionCode));
907 }
908 }
909 return ERR_OK;
910 }
911
UpdateBundleFormInfos(std::map<std::string,std::uint32_t> & bundleVersionMap,int32_t userId)912 void FormInfoMgr::UpdateBundleFormInfos(std::map<std::string, std::uint32_t> &bundleVersionMap, int32_t userId)
913 {
914 std::string versionCode;
915 FormInfoRdbStorageMgr::GetInstance().GetFormVersionCode(versionCode);
916 bool isNeedUpdateAll = versionCode.empty() || Constants::FORM_VERSION_CODE > std::stoi(versionCode);
917 HILOG_INFO("bundle number:%{public}zu, old versionCode:%{public}s, new versionCode:%{public}d",
918 bundleVersionMap.size(), versionCode.c_str(), Constants::FORM_VERSION_CODE);
919 for (auto const &bundleFormInfoPair : bundleFormInfoMap_) {
920 const std::string &bundleName = bundleFormInfoPair.first;
921 auto bundleVersionPair = bundleVersionMap.find(bundleName);
922 if (bundleVersionPair == bundleVersionMap.end()) {
923 bundleFormInfoPair.second->Remove(userId);
924 HILOG_INFO("remove forms info success, bundleName=%{public}s", bundleName.c_str());
925 continue;
926 }
927 if (!isNeedUpdateAll) {
928 uint32_t newVersionCode = bundleVersionPair->second;
929 uint32_t oldVersionCode = bundleFormInfoPair.second->GetVersionCode(userId);
930 HILOG_INFO("bundleName=%{public}s, bundle version old:%{public}d, new:%{public}d",
931 bundleName.c_str(), oldVersionCode, newVersionCode);
932 if (oldVersionCode == newVersionCode) {
933 bundleVersionMap.erase(bundleVersionPair);
934 continue;
935 }
936 }
937 bundleVersionMap.erase(bundleVersionPair);
938 bundleFormInfoPair.second->UpdateStaticFormInfos(userId);
939 HILOG_INFO("update forms info success, bundleName=%{public}s", bundleName.c_str());
940 }
941 if (isNeedUpdateAll) {
942 FormInfoRdbStorageMgr::GetInstance().UpdateFormVersionCode();
943 }
944 }
945 } // namespace AppExecFwk
946 } // namespace OHOS
947