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 }