• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "default_app_mgr.h"
17 
18 #include "bundle_data_mgr.h"
19 #include "bundle_mgr_service.h"
20 #include "bundle_permission_mgr.h"
21 #include "default_app_rdb.h"
22 #include "ipc_skeleton.h"
23 #include "mime_type_mgr.h"
24 #include "string_ex.h"
25 
26 namespace OHOS {
27 namespace AppExecFwk {
28 using Want = OHOS::AAFwk::Want;
29 
30 namespace {
31 constexpr int32_t INITIAL_USER_ID = -1;
32 constexpr int32_t TYPE_PART_COUNT = 2;
33 constexpr int32_t INDEX_ZERO = 0;
34 constexpr int32_t INDEX_ONE = 1;
35 const std::string SPLIT = "/";
36 const std::string EMAIL_ACTION = "ohos.want.action.sendToData";
37 const std::string EMAIL_SCHEME = "mailto";
38 const std::string ENTITY_BROWSER = "entity.system.browsable";
39 const std::string HTTP = "http";
40 const std::string HTTPS = "https";
41 const std::string HTTP_SCHEME = "http://";
42 const std::string HTTPS_SCHEME = "https://";
43 const std::string WILDCARD = "*";
44 const std::string BROWSER = "BROWSER";
45 const std::string IMAGE = "IMAGE";
46 const std::string AUDIO = "AUDIO";
47 const std::string VIDEO = "VIDEO";
48 const std::string PDF = "PDF";
49 const std::string WORD = "WORD";
50 const std::string EXCEL = "EXCEL";
51 const std::string PPT = "PPT";
52 const std::string EMAIL = "EMAIL";
53 const std::map<std::string, std::set<std::string>> APP_TYPES = {
54     {IMAGE, {"image/*"}},
55     {AUDIO, {"audio/*"}},
56     {VIDEO, {"video/*"}},
57     {PDF, {"application/pdf"}},
58     {WORD, {"application/msword",
59         "application/vnd.ms-word.document",
60         "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
61         "application/vnd.openxmlformats-officedocument.wordprocessingml.template"}},
62     {EXCEL, {"application/vnd.ms-excel",
63         "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
64         "application/vnd.openxmlformats-officedocument.spreadsheetml.template"}},
65     {PPT, {"application/vnd.ms-powerpoint",
66         "application/vnd.openxmlformats-officedocument.presentationml.presentation",
67         "application/vnd.openxmlformats-officedocument.presentationml.template"}},
68 };
69 const std::set<std::string> supportAppTypes = {BROWSER, IMAGE, AUDIO, VIDEO, PDF, WORD, EXCEL, PPT, EMAIL};
70 }
71 
GetInstance()72 DefaultAppMgr& DefaultAppMgr::GetInstance()
73 {
74     static DefaultAppMgr defaultAppMgr;
75     return defaultAppMgr;
76 }
77 
DefaultAppMgr()78 DefaultAppMgr::DefaultAppMgr()
79 {
80     APP_LOGD("create DefaultAppMgr.");
81     Init();
82 }
83 
~DefaultAppMgr()84 DefaultAppMgr::~DefaultAppMgr()
85 {
86     APP_LOGD("destroy DefaultAppMgr.");
87     defaultAppDb_->UnRegisterDeathListener();
88 }
89 
Init()90 void DefaultAppMgr::Init()
91 {
92     defaultAppDb_ = std::make_shared<DefaultAppRdb>();
93     defaultAppDb_->RegisterDeathListener();
94 }
95 
IsDefaultApplication(int32_t userId,const std::string & type,bool & isDefaultApp) const96 ErrCode DefaultAppMgr::IsDefaultApplication(int32_t userId, const std::string& type, bool& isDefaultApp) const
97 {
98     std::lock_guard<std::mutex> lock(mutex_);
99     std::string mimeType = type;
100     ConvertTypeBySuffix(mimeType);
101     if (VerifyUserIdAndType(userId, mimeType) != ERR_OK) {
102         APP_LOGW("VerifyUserIdAndType failed.");
103         isDefaultApp = false;
104         return ERR_OK;
105     }
106     Element element;
107     bool ret = defaultAppDb_->GetDefaultApplicationInfo(userId, mimeType, element);
108     if (!ret) {
109         APP_LOGW("GetDefaultApplicationInfo failed.");
110         isDefaultApp = false;
111         return ERR_OK;
112     }
113     ret = IsElementValid(userId, mimeType, element);
114     if (!ret) {
115         APP_LOGW("Element is invalid.");
116         isDefaultApp = false;
117         return ERR_OK;
118     }
119     // get bundle name via calling uid
120     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
121     if (dataMgr == nullptr) {
122         APP_LOGW("get BundleDataMgr failed.");
123         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
124     }
125     std::string callingBundleName;
126     ret = dataMgr->GetBundleNameForUid(IPCSkeleton::GetCallingUid(), callingBundleName);
127     if (!ret) {
128         APP_LOGW("GetBundleNameForUid failed.");
129         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
130     }
131     APP_LOGD("callingBundleName : %{public}s", callingBundleName.c_str());
132     isDefaultApp = element.bundleName == callingBundleName;
133     return ERR_OK;
134 }
135 
GetDefaultApplication(int32_t userId,const std::string & type,BundleInfo & bundleInfo,bool backup) const136 ErrCode DefaultAppMgr::GetDefaultApplication(
137     int32_t userId, const std::string& type, BundleInfo& bundleInfo, bool backup) const
138 {
139     APP_LOGD("begin, backup(bool) : %{public}d", backup);
140     std::lock_guard<std::mutex> lock(mutex_);
141     std::string mimeType = type;
142     ConvertTypeBySuffix(mimeType);
143 
144     ErrCode errCode = VerifyUserIdAndType(userId, mimeType);
145     if (errCode != ERR_OK) {
146         APP_LOGW("VerifyUserIdAndType failed.");
147         return errCode;
148     }
149     if (!BundlePermissionMgr::IsSystemApp()) {
150         APP_LOGE("non-system app calling system api");
151         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
152     }
153     if (!BundlePermissionMgr::IsSelfCalling() &&
154         !BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_GET_DEFAULT_APPLICATION)) {
155         APP_LOGW("verify permission ohos.permission.GET_DEFAULT_APPLICATION failed.");
156         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
157     }
158 
159     if (IsAppType(mimeType)) {
160         return GetBundleInfoByAppType(userId, mimeType, bundleInfo, backup);
161     } else if (IsFileType(mimeType)) {
162         return GetBundleInfoByFileType(userId, mimeType, bundleInfo, backup);
163     } else {
164         APP_LOGW("invalid type, not app type or file type.");
165         return ERR_BUNDLE_MANAGER_INVALID_TYPE;
166     }
167 }
168 
SetDefaultApplication(int32_t userId,const std::string & type,const Element & element) const169 ErrCode DefaultAppMgr::SetDefaultApplication(int32_t userId, const std::string& type, const Element& element) const
170 {
171     std::lock_guard<std::mutex> lock(mutex_);
172     std::string mimeType = type;
173     ConvertTypeBySuffix(mimeType);
174 
175     ErrCode errCode = VerifyUserIdAndType(userId, mimeType);
176     if (errCode != ERR_OK) {
177         APP_LOGW("VerifyUserIdAndType failed.");
178         return errCode;
179     }
180     if (!BundlePermissionMgr::IsSystemApp()) {
181         APP_LOGE("non-system app calling system api");
182         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
183     }
184     if (!BundlePermissionMgr::IsSelfCalling() &&
185         !BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_SET_DEFAULT_APPLICATION)) {
186         APP_LOGW("verify permission ohos.permission.SET_DEFAULT_APPLICATION failed.");
187         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
188     }
189 
190     // clear default app
191     bool ret = IsElementEmpty(element);
192     if (ret) {
193         APP_LOGD("clear default app.");
194         ret = defaultAppDb_->DeleteDefaultApplicationInfo(userId, mimeType);
195         if (!ret) {
196             APP_LOGW("DeleteDefaultApplicationInfo failed.");
197             return ERR_BUNDLE_MANAGER_ABILITY_AND_TYPE_MISMATCH;
198         }
199         APP_LOGD("SetDefaultApplication success.");
200         return ERR_OK;
201     }
202     ret = IsElementValid(userId, mimeType, element);
203     if (!ret) {
204         APP_LOGW("Element is invalid.");
205         return ERR_BUNDLE_MANAGER_ABILITY_AND_TYPE_MISMATCH;
206     }
207     ret = defaultAppDb_->SetDefaultApplicationInfo(userId, mimeType, element);
208     if (!ret) {
209         APP_LOGW("SetDefaultApplicationInfo failed.");
210         return ERR_BUNDLE_MANAGER_ABILITY_AND_TYPE_MISMATCH;
211     }
212     APP_LOGD("SetDefaultApplication success.");
213     return ERR_OK;
214 }
215 
ResetDefaultApplication(int32_t userId,const std::string & type) const216 ErrCode DefaultAppMgr::ResetDefaultApplication(int32_t userId, const std::string& type) const
217 {
218     std::lock_guard<std::mutex> lock(mutex_);
219     std::string mimeType = type;
220     ConvertTypeBySuffix(mimeType);
221 
222     ErrCode errCode = VerifyUserIdAndType(userId, mimeType);
223     if (errCode != ERR_OK) {
224         APP_LOGW("VerifyUserIdAndType failed.");
225         return errCode;
226     }
227     if (!BundlePermissionMgr::IsSystemApp()) {
228         APP_LOGE("non-system app calling system api");
229         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
230     }
231     if (!BundlePermissionMgr::IsSelfCalling() &&
232         !BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_SET_DEFAULT_APPLICATION)) {
233         APP_LOGW("verify permission ohos.permission.SET_DEFAULT_APPLICATION failed.");
234         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
235     }
236 
237     Element element;
238     bool ret = defaultAppDb_->GetDefaultApplicationInfo(INITIAL_USER_ID, mimeType, element);
239     if (!ret) {
240         APP_LOGD("directly delete default info.");
241         if (defaultAppDb_->DeleteDefaultApplicationInfo(userId, mimeType)) {
242             return ERR_OK;
243         }
244         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
245     }
246     ret = IsElementValid(userId, mimeType, element);
247     if (!ret) {
248         APP_LOGW("Element is invalid.");
249         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
250     }
251     ret = defaultAppDb_->SetDefaultApplicationInfo(userId, mimeType, element);
252     if (!ret) {
253         APP_LOGW("SetDefaultApplicationInfo failed.");
254         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
255     }
256     APP_LOGD("ResetDefaultApplication success.");
257     return ERR_OK;
258 }
259 
HandleUninstallBundle(int32_t userId,const std::string & bundleName) const260 void DefaultAppMgr::HandleUninstallBundle(int32_t userId, const std::string& bundleName) const
261 {
262     std::lock_guard<std::mutex> lock(mutex_);
263     APP_LOGD("begin");
264     std::map<std::string, Element> currentInfos;
265     bool ret = defaultAppDb_->GetDefaultApplicationInfos(userId, currentInfos);
266     if (!ret) {
267         APP_LOGW("GetDefaultApplicationInfos failed");
268         return;
269     }
270     // if type exist in default_app.json, use it
271     std::map<std::string, Element> newInfos;
272     for (const auto& item : currentInfos) {
273         if (item.second.bundleName == bundleName) {
274             Element element;
275             if (defaultAppDb_->GetDefaultApplicationInfo(INITIAL_USER_ID, item.first, element)) {
276                 APP_LOGD("set default application to preset, type : %{public}s", item.first.c_str());
277                 newInfos.emplace(item.first, element);
278             } else {
279                 APP_LOGD("erase uninstalled default application, type : %{public}s", item.first.c_str());
280             }
281         } else {
282             newInfos.emplace(item.first, item.second);
283         }
284     }
285     defaultAppDb_->SetDefaultApplicationInfos(userId, newInfos);
286 }
287 
HandleCreateUser(int32_t userId) const288 void DefaultAppMgr::HandleCreateUser(int32_t userId) const
289 {
290     std::lock_guard<std::mutex> lock(mutex_);
291     APP_LOGD("begin");
292     std::map<std::string, Element> infos;
293     bool ret = defaultAppDb_->GetDefaultApplicationInfos(INITIAL_USER_ID, infos);
294     if (!ret) {
295         APP_LOGW("GetDefaultApplicationInfos failed");
296         return;
297     }
298     defaultAppDb_->SetDefaultApplicationInfos(userId, infos);
299 }
300 
HandleRemoveUser(int32_t userId) const301 void DefaultAppMgr::HandleRemoveUser(int32_t userId) const
302 {
303     std::lock_guard<std::mutex> lock(mutex_);
304     APP_LOGD("begin");
305     defaultAppDb_->DeleteDefaultApplicationInfos(userId);
306 }
307 
IsBrowserWant(const Want & want) const308 bool DefaultAppMgr::IsBrowserWant(const Want& want) const
309 {
310     bool matchAction = want.GetAction() == Constants::ACTION_VIEW_DATA;
311     if (!matchAction) {
312         APP_LOGD("Action does not match, not browser want");
313         return false;
314     }
315     std::string uri = want.GetUriString();
316     bool matchUri = uri.rfind(HTTP_SCHEME, 0) == 0 || uri.rfind(HTTPS_SCHEME, 0) == 0;
317     if (!matchUri) {
318         APP_LOGD("Uri does not match, not browser want");
319         return false;
320     }
321     APP_LOGD("is browser want");
322     return true;
323 }
324 
IsEmailWant(const Want & want) const325 bool DefaultAppMgr::IsEmailWant(const Want& want) const
326 {
327     bool matchAction = want.GetAction() == EMAIL_ACTION;
328     if (!matchAction) {
329         APP_LOGD("Action does not match, not email want");
330         return false;
331     }
332     std::string uri = want.GetUriString();
333     bool matchUri = uri.rfind(EMAIL_SCHEME, 0) == 0;
334     if (!matchUri) {
335         APP_LOGD("Uri does not match, not email want");
336         return false;
337     }
338     APP_LOGD("is email want");
339     return true;
340 }
341 
GetType(const Want & want) const342 std::string DefaultAppMgr::GetType(const Want& want) const
343 {
344     if (IsBrowserWant(want)) {
345         return BROWSER;
346     }
347     if (IsEmailWant(want)) {
348         return EMAIL;
349     }
350     if (want.GetAction() == Constants::ACTION_VIEW_DATA) {
351         std::string type = want.GetType();
352         if (!type.empty()) {
353             return type;
354         }
355         std::string uri = want.GetUriString();
356         if (uri.empty()) {
357             return Constants::EMPTY_STRING;
358         }
359         std::string convertType;
360         if (MimeTypeMgr::GetMimeTypeByUri(uri, convertType)) {
361             APP_LOGD("get type by uri success, convertType : %{public}s", convertType.c_str());
362             return convertType;
363         }
364         return Constants::EMPTY_STRING;
365     }
366     return Constants::EMPTY_STRING;
367 }
368 
GetDefaultApplication(const Want & want,const int32_t userId,std::vector<AbilityInfo> & abilityInfos,std::vector<ExtensionAbilityInfo> & extensionInfos,bool backup) const369 bool DefaultAppMgr::GetDefaultApplication(const Want& want, const int32_t userId,
370     std::vector<AbilityInfo>& abilityInfos, std::vector<ExtensionAbilityInfo>& extensionInfos, bool backup) const
371 {
372     APP_LOGD("begin, backup(bool) : %{public}d", backup);
373     std::string type = GetType(want);
374     APP_LOGI("type : %{public}s", type.c_str());
375     if (type.empty()) {
376         APP_LOGE("GetType failed");
377         return false;
378     }
379     BundleInfo bundleInfo;
380     ErrCode ret = GetDefaultApplication(userId, type, bundleInfo, backup);
381     if (ret != ERR_OK) {
382         APP_LOGE("GetDefaultApplication failed");
383         return false;
384     }
385 
386     std::string bundleName = want.GetElement().GetBundleName();
387     if (!bundleName.empty() && bundleName != bundleInfo.name) {
388         APP_LOGD("request bundleName : %{public}s, default bundleName : %{public}s",
389             bundleName.c_str(), bundleInfo.name.c_str());
390         return false;
391     }
392 
393     if (bundleInfo.abilityInfos.size() == 1) {
394         abilityInfos = bundleInfo.abilityInfos;
395         APP_LOGD("find default ability");
396         return true;
397     } else if (bundleInfo.extensionInfos.size() == 1) {
398         extensionInfos = bundleInfo.extensionInfos;
399         APP_LOGD("find default extension");
400         return true;
401     } else {
402         APP_LOGE("invalid bundleInfo");
403         return false;
404     }
405 }
406 
GetBundleInfoByAppType(int32_t userId,const std::string & type,BundleInfo & bundleInfo,bool backup) const407 ErrCode DefaultAppMgr::GetBundleInfoByAppType(
408     int32_t userId, const std::string& type, BundleInfo& bundleInfo, bool backup) const
409 {
410     int32_t key = backup ? Constants::BACKUP_DEFAULT_APP_KEY : userId;
411     Element element;
412     bool ret = defaultAppDb_->GetDefaultApplicationInfo(key, type, element);
413     if (!ret) {
414         APP_LOGW("GetDefaultApplicationInfo failed.");
415         return ERR_BUNDLE_MANAGER_DEFAULT_APP_NOT_EXIST;
416     }
417     ret = GetBundleInfo(userId, type, element, bundleInfo);
418     if (!ret) {
419         APP_LOGW("GetBundleInfo failed.");
420         return ERR_BUNDLE_MANAGER_DEFAULT_APP_NOT_EXIST;
421     }
422     APP_LOGD("GetBundleInfoByAppType success.");
423     return ERR_OK;
424 }
425 
GetBundleInfoByFileType(int32_t userId,const std::string & type,BundleInfo & bundleInfo,bool backup) const426 ErrCode DefaultAppMgr::GetBundleInfoByFileType(
427     int32_t userId, const std::string& type, BundleInfo& bundleInfo, bool backup) const
428 {
429     int32_t key = backup ? Constants::BACKUP_DEFAULT_APP_KEY : userId;
430     std::map<std::string, Element> infos;
431     bool ret = defaultAppDb_->GetDefaultApplicationInfos(key, infos);
432     if (!ret) {
433         APP_LOGW("GetDefaultApplicationInfos failed.");
434         return ERR_BUNDLE_MANAGER_DEFAULT_APP_NOT_EXIST;
435     }
436     std::map<std::string, Element> defaultAppTypeInfos;
437     std::map<std::string, Element> defaultFileTypeInfos;
438     for (const auto& item : infos) {
439         if (IsAppType(item.first)) {
440             defaultAppTypeInfos.emplace(item.first, item.second);
441         }
442         if (IsFileType(item.first)) {
443             defaultFileTypeInfos.emplace(item.first, item.second);
444         }
445     }
446     // match default app type
447     for (const auto& item : defaultAppTypeInfos) {
448         const auto iter = APP_TYPES.find(item.first);
449         if (iter == APP_TYPES.end()) {
450             continue;
451         }
452         Skill skill;
453         for (const auto& mimeType : iter->second) {
454             if (skill.MatchType(type, mimeType) && GetBundleInfo(userId, type, item.second, bundleInfo)) {
455                 APP_LOGD("match default app type success");
456                 return ERR_OK;
457             }
458         }
459     }
460     // match default file type
461     for (const auto& item : defaultFileTypeInfos) {
462         if (item.first == type && GetBundleInfo(userId, type, item.second, bundleInfo)) {
463             APP_LOGD("match default file type success.");
464             return ERR_OK;
465         }
466     }
467     APP_LOGW("GetBundleInfoByFileType failed.");
468     return ERR_BUNDLE_MANAGER_DEFAULT_APP_NOT_EXIST;
469 }
470 
GetBundleInfo(int32_t userId,const std::string & type,const Element & element,BundleInfo & bundleInfo) const471 bool DefaultAppMgr::GetBundleInfo(int32_t userId, const std::string& type, const Element& element,
472     BundleInfo& bundleInfo) const
473 {
474     APP_LOGD("begin to GetBundleInfo.");
475     bool ret = VerifyElementFormat(element);
476     if (!ret) {
477         APP_LOGW("VerifyElementFormat failed.");
478         return false;
479     }
480     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
481     if (dataMgr == nullptr) {
482         APP_LOGW("get BundleDataMgr failed.");
483         return false;
484     }
485     AbilityInfo abilityInfo;
486     ExtensionAbilityInfo extensionInfo;
487     std::vector<Skill> skills;
488     // verify if element exists
489     ret = dataMgr->QueryInfoAndSkillsByElement(userId, element, abilityInfo, extensionInfo, skills);
490     if (!ret) {
491         APP_LOGW("GetBundleInfo, QueryInfoAndSkillsByElement failed.");
492         return false;
493     }
494     // match type and skills
495     ret = IsMatch(type, skills);
496     if (!ret) {
497         APP_LOGW("GetBundleInfo, type and skills not match.");
498         return false;
499     }
500     ret = dataMgr->GetBundleInfo(element.bundleName, GET_BUNDLE_DEFAULT, bundleInfo, userId);
501     if (!ret) {
502         APP_LOGW("GetBundleInfo failed.");
503         return false;
504     }
505     bool isAbility = !element.abilityName.empty();
506     if (isAbility) {
507         bundleInfo.abilityInfos.emplace_back(abilityInfo);
508     } else {
509         bundleInfo.extensionInfos.emplace_back(extensionInfo);
510     }
511     APP_LOGD("GetBundleInfo success.");
512     return true;
513 }
514 
MatchActionAndType(const std::string & action,const std::string & type,const std::vector<Skill> & skills) const515 bool DefaultAppMgr::MatchActionAndType(
516     const std::string& action, const std::string& type, const std::vector<Skill>& skills) const
517 {
518     APP_LOGD("begin, action : %{public}s, type : %{public}s", action.c_str(), type.c_str());
519     for (const Skill& skill : skills) {
520         auto item = std::find(skill.actions.cbegin(), skill.actions.cend(), action);
521         if (item == skill.actions.cend()) {
522             continue;
523         }
524         for (const SkillUri& skillUri : skill.uris) {
525             if (skill.MatchType(type, skillUri.type)) {
526                 return true;
527             }
528         }
529     }
530     APP_LOGW("MatchActionAndType failed");
531     return false;
532 }
533 
IsMatch(const std::string & type,const std::vector<Skill> & skills) const534 bool DefaultAppMgr::IsMatch(const std::string& type, const std::vector<Skill>& skills) const
535 {
536     if (IsAppType(type)) {
537         return MatchAppType(type, skills);
538     } else if (IsFileType(type)) {
539         return MatchFileType(type, skills);
540     } else {
541         APP_LOGW("invalid type.");
542         return false;
543     }
544 }
545 
MatchAppType(const std::string & type,const std::vector<Skill> & skills) const546 bool DefaultAppMgr::MatchAppType(const std::string& type, const std::vector<Skill>& skills) const
547 {
548     APP_LOGW("begin to match app type, type : %{public}s.", type.c_str());
549     if (type == BROWSER) {
550         return IsBrowserSkillsValid(skills);
551     }
552     if (type == EMAIL) {
553         return IsEmailSkillsValid(skills);
554     }
555     auto item = APP_TYPES.find(type);
556     if (item == APP_TYPES.end()) {
557         APP_LOGE("invalid app type : %{public}s.", type.c_str());
558         return false;
559     }
560     for (const std::string& mimeType : item->second) {
561         if (MatchActionAndType(Constants::ACTION_VIEW_DATA, mimeType, skills)) {
562             return true;
563         }
564     }
565     return false;
566 }
567 
IsBrowserSkillsValid(const std::vector<Skill> & skills) const568 bool DefaultAppMgr::IsBrowserSkillsValid(const std::vector<Skill>& skills) const
569 {
570     APP_LOGD("begin to verify browser skills.");
571     Want httpWant;
572     httpWant.SetAction(Constants::ACTION_VIEW_DATA);
573     httpWant.AddEntity(ENTITY_BROWSER);
574     httpWant.SetUri(HTTP);
575 
576     Want httpsWant;
577     httpsWant.SetAction(Constants::ACTION_VIEW_DATA);
578     httpsWant.AddEntity(ENTITY_BROWSER);
579     httpsWant.SetUri(HTTPS);
580     for (const Skill& skill : skills) {
581         if (skill.Match(httpsWant) || skill.Match(httpWant)) {
582             APP_LOGD("browser skills is valid");
583             return true;
584         }
585     }
586     APP_LOGW("browser skills is invalid.");
587     return false;
588 }
589 
IsEmailSkillsValid(const std::vector<Skill> & skills) const590 bool DefaultAppMgr::IsEmailSkillsValid(const std::vector<Skill>& skills) const
591 {
592     APP_LOGD("begin to verify email skills");
593     Want want;
594     want.SetAction(EMAIL_ACTION);
595     want.SetUri(EMAIL_SCHEME);
596 
597     for (const Skill& skill : skills) {
598         if (skill.Match(want)) {
599             APP_LOGD("email skills valid");
600             return true;
601         }
602     }
603     APP_LOGW("email skills invalid");
604     return false;
605 }
606 
MatchFileType(const std::string & type,const std::vector<Skill> & skills) const607 bool DefaultAppMgr::MatchFileType(const std::string& type, const std::vector<Skill>& skills) const
608 {
609     APP_LOGD("type : %{public}s", type.c_str());
610     if (MatchActionAndType(Constants::ACTION_VIEW_DATA, type, skills)) {
611         return true;
612     }
613     APP_LOGE("MatchFileType failed");
614     return false;
615 }
616 
IsTypeValid(const std::string & type) const617 bool DefaultAppMgr::IsTypeValid(const std::string& type) const
618 {
619     return IsAppType(type) || IsFileType(type);
620 }
621 
IsAppType(const std::string & type) const622 bool DefaultAppMgr::IsAppType(const std::string& type) const
623 {
624     if (type.empty()) {
625         return false;
626     }
627     return supportAppTypes.find(type) != supportAppTypes.end();
628 }
629 
IsFileType(const std::string & type) const630 bool DefaultAppMgr::IsFileType(const std::string& type) const
631 {
632     // valid fileType format : type/subType
633     if (type.empty() || type.find(WILDCARD) != type.npos) {
634         APP_LOGW("file type not allow contains *.");
635         return false;
636     }
637     std::vector<std::string> vector;
638     SplitStr(type, SPLIT, vector, false, false);
639     if (vector.size() == TYPE_PART_COUNT && !vector[INDEX_ZERO].empty() && !vector[INDEX_ONE].empty()) {
640         return true;
641     }
642     APP_LOGW("file type format invalid.");
643     return false;
644 }
645 
IsUserIdExist(int32_t userId) const646 bool DefaultAppMgr::IsUserIdExist(int32_t userId) const
647 {
648     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
649     if (dataMgr == nullptr) {
650         APP_LOGW("get BundleDataMgr failed.");
651         return false;
652     }
653     return dataMgr->HasUserId(userId);
654 }
655 
VerifyUserIdAndType(int32_t userId,const std::string & type) const656 ErrCode DefaultAppMgr::VerifyUserIdAndType(int32_t userId, const std::string& type) const
657 {
658     bool ret = IsUserIdExist(userId);
659     if (!ret) {
660         APP_LOGW("userId %{public}d doesn't exist.", userId);
661         return ERR_BUNDLE_MANAGER_INVALID_USER_ID;
662     }
663     ret = IsTypeValid(type);
664     if (!ret) {
665         APP_LOGW("invalid type %{public}s, not app type or file type.", type.c_str());
666         return ERR_BUNDLE_MANAGER_INVALID_TYPE;
667     }
668     return ERR_OK;
669 }
670 
IsElementEmpty(const Element & element) const671 bool DefaultAppMgr::IsElementEmpty(const Element& element) const
672 {
673     return element.bundleName.empty() && element.moduleName.empty()
674         && element.abilityName.empty() && element.extensionName.empty();
675 }
676 
VerifyElementFormat(const Element & element)677 bool DefaultAppMgr::VerifyElementFormat(const Element& element)
678 {
679     const std::string& bundleName = element.bundleName;
680     const std::string& moduleName = element.moduleName;
681     const std::string& abilityName = element.abilityName;
682     const std::string& extensionName = element.extensionName;
683     if (bundleName.empty()) {
684         APP_LOGW("bundleName empty, bad Element format.");
685         return false;
686     }
687     if (moduleName.empty()) {
688         APP_LOGW("moduleName empty, bad Element format.");
689         return false;
690     }
691     if (abilityName.empty() && extensionName.empty()) {
692         APP_LOGW("abilityName and extensionName both empty, bad Element format.");
693         return false;
694     }
695     if (!abilityName.empty() && !extensionName.empty()) {
696         APP_LOGW("abilityName and extensionName both non-empty, bad Element format.");
697         return false;
698     }
699     return true;
700 }
701 
IsElementValid(int32_t userId,const std::string & type,const Element & element) const702 bool DefaultAppMgr::IsElementValid(int32_t userId, const std::string& type, const Element& element) const
703 {
704     bool ret = VerifyElementFormat(element);
705     if (!ret) {
706         APP_LOGW("VerifyElementFormat failed.");
707         return false;
708     }
709     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
710     if (dataMgr == nullptr) {
711         APP_LOGW("get BundleDataMgr failed.");
712         return false;
713     }
714     AbilityInfo abilityInfo;
715     ExtensionAbilityInfo extensionInfo;
716     std::vector<Skill> skills;
717     // verify if element exists
718     ret = dataMgr->QueryInfoAndSkillsByElement(userId, element, abilityInfo, extensionInfo, skills);
719     if (!ret) {
720         APP_LOGW("QueryInfoAndSkillsByElement failed.");
721         return false;
722     }
723     // match type and skills
724     ret = IsMatch(type, skills);
725     if (!ret) {
726         APP_LOGW("type and skills not match.");
727         return false;
728     }
729     APP_LOGD("Element is valid.");
730     return true;
731 }
732 
ConvertTypeBySuffix(std::string & suffix) const733 void DefaultAppMgr::ConvertTypeBySuffix(std::string& suffix) const
734 {
735     if (suffix.empty() || suffix.find('.') != 0) {
736         APP_LOGD("default app type is not suffix form");
737         return;
738     }
739 
740     std::string type;
741     bool ret = MimeTypeMgr::GetMimeTypeByUri(suffix, type);
742     if (!ret) {
743         APP_LOGW("uri suffix %{public}s has no corresponding mime type", suffix.c_str());
744         return;
745     }
746     APP_LOGD("corresponding mime type is %{public}s", type.c_str());
747     suffix = type;
748     return;
749 }
750 }
751 }