• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <utility>
19 
20 #include "bundle_mgr_client.h"
21 #include "extension_form_profile.h"
22 #include "form_bms_helper.h"
23 #include "form_info_storage.h"
24 #include "form_info_storage_mgr.h"
25 #include "form_util.h"
26 #include "hilog_wrapper.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     if (bundleName.empty()) {
42         HILOG_ERROR("bundleName is invalid");
43         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
44     }
45 
46     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
47     if (iBundleMgr == nullptr) {
48         HILOG_ERROR("GetBundleMgr, failed to get IBundleMgr.");
49         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
50     }
51 
52     BundleInfo bundleInfo;
53     if (!IN_PROCESS_CALL(iBundleMgr->GetBundleInfo(bundleName, GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId))) {
54         HILOG_ERROR("failed to get bundle info.");
55         return ERR_APPEXECFWK_FORM_GET_INFO_FAILED;
56     }
57 
58     ErrCode errCode = LoadAbilityFormConfigInfo(bundleInfo, formInfos);
59     if (errCode != ERR_OK) {
60         HILOG_ERROR("failed to load FA form config info, error code=%{public}d.", errCode);
61     }
62 
63     errCode = LoadStageFormConfigInfo(bundleInfo, formInfos);
64     if (errCode != ERR_OK) {
65         HILOG_ERROR("failed to load stage form config info, error code=%{public}d.", errCode);
66     }
67 
68     return ERR_OK;
69 }
70 
LoadStageFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)71 ErrCode FormInfoHelper::LoadStageFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
72 {
73     std::shared_ptr<BundleMgrClient> client = DelayedSingleton<BundleMgrClient>::GetInstance();
74     if (client == nullptr) {
75         HILOG_ERROR("failed to get BundleMgrClient.");
76         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
77     }
78 
79     for (auto const &extensionInfo: bundleInfo.extensionInfos) {
80         if (extensionInfo.type != ExtensionAbilityType::FORM) {
81             continue;
82         }
83 
84         std::vector<std::string> profileInfos {};
85         if (!client->GetResConfigFile(extensionInfo, FORM_METADATA_NAME, profileInfos)) {
86             HILOG_ERROR("failed to get form metadata.");
87             continue;
88         }
89 
90         for (const auto &profileInfo: profileInfos) {
91             std::vector<ExtensionFormInfo> extensionFormInfos;
92             ErrCode errCode = ExtensionFormProfile::TransformTo(profileInfo, extensionFormInfos);
93             if (errCode != ERR_OK) {
94                 HILOG_WARN("failed to transform profile to extension form info");
95                 continue;
96             }
97             for (const auto &extensionFormInfo: extensionFormInfos) {
98                 formInfos.emplace_back(extensionInfo, extensionFormInfo);
99             }
100         }
101     }
102     return ERR_OK;
103 }
104 
LoadAbilityFormConfigInfo(const BundleInfo & bundleInfo,std::vector<FormInfo> & formInfos)105 ErrCode FormInfoHelper::LoadAbilityFormConfigInfo(const BundleInfo &bundleInfo, std::vector<FormInfo> &formInfos)
106 {
107     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
108     if (iBundleMgr == nullptr) {
109         HILOG_ERROR("failed to get IBundleMgr.");
110         return ERR_APPEXECFWK_FORM_GET_BMS_FAILED;
111     }
112 
113     const std::string &bundleName = bundleInfo.name;
114     for (const auto &modelInfo: bundleInfo.hapModuleInfos) {
115         const std::string &moduleName = modelInfo.moduleName;
116         std::vector<FormInfo> formInfoVec {};
117         if (!IN_PROCESS_CALL(iBundleMgr->GetFormsInfoByModule(bundleName, moduleName, formInfoVec))) {
118             continue;
119         }
120         for (const auto &formInfo: formInfoVec) {
121             // check form info
122             formInfos.push_back(formInfo);
123         }
124     }
125 
126     return ERR_OK;
127 }
128 
BundleFormInfo(std::string bundleName)129 BundleFormInfo::BundleFormInfo(std::string bundleName) : bundleName_(std::move(bundleName))
130 {
131 }
132 
InitFromJson(const std::string & formInfoStoragesJson)133 ErrCode BundleFormInfo::InitFromJson(const std::string &formInfoStoragesJson)
134 {
135     nlohmann::json jsonObject = nlohmann::json::parse(formInfoStoragesJson, nullptr, false);
136     if (jsonObject.is_discarded()) {
137         HILOG_ERROR("bad profile");
138         return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
139     }
140     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
141     std::vector<AAFwk::FormInfoStorage> formInfoStorages = jsonObject.get<std::vector<AAFwk::FormInfoStorage>>();
142     for (const auto &item : formInfoStorages) {
143         formInfoStorages_.push_back(item);
144     }
145     return ERR_OK;
146 }
147 
Update(int32_t userId)148 ErrCode BundleFormInfo::Update(int32_t userId)
149 {
150     HILOG_INFO("Update form infos, userId is %{public}d.", userId);
151     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
152     std::vector<FormInfo> formInfos;
153     ErrCode errCode = FormInfoHelper::LoadFormConfigInfoByBundleName(bundleName_, formInfos, userId);
154     if (errCode != ERR_OK) {
155         return errCode;
156     }
157 
158     for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
159         if (item->userId == userId) {
160             item = formInfoStorages_.erase(item);
161         } else {
162             ++item;
163         }
164     }
165 
166     if (!formInfos.empty()) {
167         AAFwk::FormInfoStorage formInfoStorage(userId, formInfos);
168         formInfoStorages_.push_back(formInfoStorage);
169     }
170 
171     if (formInfoStorages_.empty()) {
172         HILOG_INFO("form info Storages is empty.");
173         return ERR_OK;
174     }
175 
176     nlohmann::json jsonObject = formInfoStorages_;
177     if (jsonObject.is_discarded()) {
178         HILOG_ERROR("bad form infos.");
179         return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
180     }
181     std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
182     errCode = FormInfoStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
183     return errCode;
184 }
185 
Remove(int32_t userId)186 ErrCode BundleFormInfo::Remove(int32_t userId)
187 {
188     HILOG_INFO("Remove form infos, userId is %{public}d.", userId);
189     std::unique_lock<std::shared_timed_mutex> guard(formInfosMutex_);
190     for (auto item = formInfoStorages_.begin(); item != formInfoStorages_.end();) {
191         if (item->userId == userId) {
192             item = formInfoStorages_.erase(item);
193         } else {
194             ++item;
195         }
196     }
197 
198     ErrCode errCode;
199     if (formInfoStorages_.empty()) {
200         errCode = FormInfoStorageMgr::GetInstance().RemoveBundleFormInfos(bundleName_);
201     } else {
202         nlohmann::json jsonObject = formInfoStorages_;
203         if (jsonObject.is_discarded()) {
204             HILOG_ERROR("bad form infos.");
205             return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
206         }
207         std::string formInfoStoragesStr = jsonObject.dump(Constants::DUMP_INDENT);
208         errCode = FormInfoStorageMgr::GetInstance().UpdateBundleFormInfos(bundleName_, formInfoStoragesStr);
209     }
210 
211     return errCode;
212 }
213 
Empty()214 bool BundleFormInfo::Empty()
215 {
216     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
217     return formInfoStorages_.empty();
218 }
219 
GetAllFormsInfo(std::vector<FormInfo> & formInfos)220 ErrCode BundleFormInfo::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
221 {
222     HILOG_INFO("%{public}s begin.",  __func__);
223     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
224     int32_t userId = FormUtil::GetCurrentAccountId();
225     for (const auto &item : formInfoStorages_) {
226         item.GetAllFormsInfo(userId, formInfos);
227     }
228     return ERR_OK;
229 }
230 
GetFormsInfoByModule(const std::string & moduleName,std::vector<FormInfo> & formInfos)231 ErrCode BundleFormInfo::GetFormsInfoByModule(const std::string &moduleName, std::vector<FormInfo> &formInfos)
232 {
233     std::shared_lock<std::shared_timed_mutex> guard(formInfosMutex_);
234     int32_t userId = FormUtil::GetCurrentAccountId();
235     for (const auto &item : formInfoStorages_) {
236         item.GetFormsInfoByModule(userId, moduleName, formInfos);
237     }
238     return ERR_OK;
239 }
240 
FormInfoMgr()241 FormInfoMgr::FormInfoMgr()
242 {
243     HILOG_INFO("FormInfoMgr is created");
244 }
245 
246 FormInfoMgr::~FormInfoMgr() = default;
247 
Start()248 ErrCode FormInfoMgr::Start()
249 {
250     std::vector<std::pair<std::string, std::string>> formInfoStorages;
251     ErrCode errCode = FormInfoStorageMgr::GetInstance().LoadFormInfos(formInfoStorages);
252     if (errCode != ERR_OK) {
253         HILOG_ERROR("LoadFormData failed.");
254         return errCode;
255     }
256 
257     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
258     for (const auto &item: formInfoStorages) {
259         const std::string &bundleName = item.first;
260         const std::string &formInfoStoragesJson = item.second;
261         auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
262         errCode = bundleFormInfoPtr->InitFromJson(formInfoStoragesJson);
263         if (errCode != ERR_OK) {
264             continue;
265         }
266         HILOG_ERROR("load bundle %{public}s form infos success.", bundleName.c_str());
267         bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
268     }
269     HILOG_INFO("load bundle form infos from db done.");
270     return ERR_OK;
271 }
272 
Update(const std::string & bundleName,int32_t userId)273 ErrCode FormInfoMgr::Update(const std::string &bundleName, int32_t userId)
274 {
275     if (bundleName.empty()) {
276         HILOG_ERROR("bundleName is empty.");
277         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
278     }
279 
280     std::shared_ptr<BundleFormInfo> bundleFormInfoPtr;
281     auto search = bundleFormInfoMap_.find(bundleName);
282     if (search != bundleFormInfoMap_.end()) {
283         bundleFormInfoPtr = search->second;
284     } else {
285         bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
286     }
287 
288     ErrCode errCode = bundleFormInfoPtr->Update(userId);
289     if (errCode != ERR_OK) {
290         return errCode;
291     }
292 
293     if (bundleFormInfoPtr->Empty()) {
294         // no forms found, no need to be inserted into the map
295         return ERR_OK;
296     }
297 
298     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
299     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
300     HILOG_ERROR("update forms info success, bundleName=%{public}s.", bundleName.c_str());
301     return ERR_OK;
302 }
303 
Remove(const std::string & bundleName,int32_t userId)304 ErrCode FormInfoMgr::Remove(const std::string &bundleName, int32_t userId)
305 {
306     if (bundleName.empty()) {
307         HILOG_ERROR("bundleName is empty.");
308         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
309     }
310 
311     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
312     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
313     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
314         // BundleFormInfo not found, no need to remove
315         return ERR_OK;
316     }
317 
318     ErrCode errCode = ERR_OK;
319     if (bundleFormInfoIter->second != nullptr) {
320         errCode = bundleFormInfoIter->second->Remove(userId);
321     }
322 
323     if (bundleFormInfoIter->second->Empty()) {
324         bundleFormInfoMap_.erase(bundleFormInfoIter);
325     }
326     HILOG_ERROR("remove forms info success, bundleName=%{public}s.", bundleName.c_str());
327     return errCode;
328 }
329 
GetAllFormsInfo(std::vector<FormInfo> & formInfos)330 ErrCode FormInfoMgr::GetAllFormsInfo(std::vector<FormInfo> &formInfos)
331 {
332     bool hasPermission = CheckBundlePermission();
333     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
334     if (hasPermission) {
335         for (const auto &bundleFormInfo: bundleFormInfoMap_) {
336             if (bundleFormInfo.second != nullptr) {
337                 bundleFormInfo.second->GetAllFormsInfo(formInfos);
338             }
339         }
340     } else {
341         for (const auto &bundleFormInfo: bundleFormInfoMap_) {
342             if (IsCaller(bundleFormInfo.first)) {
343                 if (bundleFormInfo.second != nullptr) {
344                     bundleFormInfo.second->GetAllFormsInfo(formInfos);
345                 }
346                 return ERR_OK;
347             }
348         }
349     }
350     return ERR_OK;
351 }
352 
GetFormsInfoByBundle(const std::string & bundleName,std::vector<FormInfo> & formInfos)353 ErrCode FormInfoMgr::GetFormsInfoByBundle(const std::string &bundleName, std::vector<FormInfo> &formInfos)
354 {
355     if (bundleName.empty()) {
356         HILOG_ERROR("bundleName is empty.");
357         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
358     }
359 
360     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
361         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
362     }
363 
364     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
365     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
366     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
367         HILOG_ERROR("no forms found.");
368         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
369     }
370 
371     if (bundleFormInfoIter->second != nullptr) {
372         bundleFormInfoIter->second->GetAllFormsInfo(formInfos);
373     }
374     return ERR_OK;
375 }
376 
GetFormsInfoByModule(const std::string & bundleName,const std::string & moduleName,std::vector<FormInfo> & formInfos)377 ErrCode FormInfoMgr::GetFormsInfoByModule(const std::string &bundleName, const std::string &moduleName,
378                                           std::vector<FormInfo> &formInfos)
379 {
380     if (bundleName.empty()) {
381         HILOG_ERROR("bundleName is empty.");
382         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
383     }
384 
385     if (!CheckBundlePermission() && !IsCaller(bundleName)) {
386         return ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE;
387     }
388 
389     std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
390     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
391     if (bundleFormInfoIter == bundleFormInfoMap_.end()) {
392         HILOG_ERROR("no forms found for %{public}s.", bundleName.c_str());
393         return ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED;
394     }
395 
396     if (bundleFormInfoIter->second != nullptr) {
397         bundleFormInfoIter->second->GetFormsInfoByModule(moduleName, formInfos);
398     }
399     return ERR_OK;
400 }
401 
GetOrCreateBundleFromInfo(const std::string & bundleName)402 std::shared_ptr<BundleFormInfo> FormInfoMgr::GetOrCreateBundleFromInfo(const std::string &bundleName)
403 {
404     {
405         std::shared_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
406         auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
407         if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
408             // found
409             return bundleFormInfoIter->second;
410         }
411     }
412 
413     // not found
414     std::unique_lock<std::shared_timed_mutex> guard(bundleFormInfoMapMutex_);
415     auto bundleFormInfoIter = bundleFormInfoMap_.find(bundleName);
416     // try to find again
417     if (bundleFormInfoIter != bundleFormInfoMap_.end()) {
418         // found
419         return bundleFormInfoIter->second;
420     }
421     auto bundleFormInfoPtr = std::make_shared<BundleFormInfo>(bundleName);
422     bundleFormInfoMap_[bundleName] = bundleFormInfoPtr;
423     return bundleFormInfoPtr;
424 }
425 
IsCaller(std::string bundleName)426 bool FormInfoMgr::IsCaller(std::string bundleName)
427 {
428     auto bms = FormBmsHelper::GetInstance().GetBundleMgr();
429     if (!bms) {
430         return false;
431     }
432     AppExecFwk::BundleInfo bundleInfo;
433     bool ret = IN_PROCESS_CALL(
434         bms->GetBundleInfo(bundleName, GET_BUNDLE_DEFAULT, bundleInfo, FormUtil::GetCurrentAccountId()));
435     if (!ret) {
436         HILOG_ERROR("Failed to get bundle info.");
437         return false;
438     }
439     auto callerToken = IPCSkeleton::GetCallingTokenID();
440     if (bundleInfo.applicationInfo.accessTokenId == callerToken) {
441         return true;
442     }
443     return false;
444 }
445 
CheckBundlePermission()446 bool FormInfoMgr::CheckBundlePermission()
447 {
448     auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
449     if (isSaCall) {
450         return true;
451     }
452     auto isCallingPerm = AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
453         AppExecFwk::Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
454     if (isCallingPerm) {
455         return true;
456     }
457     HILOG_ERROR("Permission verification failed");
458     return false;
459 }
460 }  // namespace AppExecFwk
461 }  // namespace OHOS
462