• 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 #include "implicit_start_processor.h"
16 
17 #include <string>
18 
19 #include "ability_manager_service.h"
20 #include "ability_util.h"
21 #include "default_app_interface.h"
22 #include "errors.h"
23 #include "event_report.h"
24 #include "hilog_wrapper.h"
25 #include "in_process_call_wrapper.h"
26 #include "parameters.h"
27 #include "want.h"
28 #ifdef SUPPORT_ERMS
29 #include "ecological_rule_mgr_service_client.h"
30 #endif
31 
32 namespace OHOS {
33 namespace AAFwk {
34 #ifdef SUPPORT_ERMS
35 using namespace OHOS::EcologicalRuleMgrService;
36 
37 constexpr int32_t TYPE_HARMONY_INVALID = 0;
38 constexpr int32_t TYPE_HARMONY_APP = 1;
39 constexpr int32_t TYPE_HARMONY_SERVICE = 2;
40 #else
41 using ErmsCallerInfo = OHOS::AppExecFwk::ErmsParams::CallerInfo;
42 #endif
43 
44 const std::string BLACK_ACTION_SELECT_DATA = "ohos.want.action.select";
45 const std::string STR_PHONE = "phone";
46 const std::string STR_DEFAULT = "default";
47 const std::string TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard";
48 const std::string SHOW_DEFAULT_PICKER_FLAG = "ohos.ability.params.showDefaultPicker";
49 
50 const std::vector<std::string> ImplicitStartProcessor::blackList = {
51     std::vector<std::string>::value_type(BLACK_ACTION_SELECT_DATA),
52 };
53 
54 const std::unordered_set<AppExecFwk::ExtensionAbilityType> ImplicitStartProcessor::extensionWhiteList = {
55     AppExecFwk::ExtensionAbilityType::FORM,
56     AppExecFwk::ExtensionAbilityType::INPUTMETHOD,
57     AppExecFwk::ExtensionAbilityType::WALLPAPER,
58     AppExecFwk::ExtensionAbilityType::WINDOW,
59     AppExecFwk::ExtensionAbilityType::THUMBNAIL,
60     AppExecFwk::ExtensionAbilityType::PREVIEW
61 };
62 
IsImplicitStartAction(const Want & want)63 bool ImplicitStartProcessor::IsImplicitStartAction(const Want &want)
64 {
65     auto element = want.GetElement();
66     if (!element.GetAbilityName().empty()) {
67         return false;
68     }
69 
70     if (std::find(blackList.begin(), blackList.end(), want.GetAction()) == blackList.end()) {
71         HILOG_INFO("implicit start, the action is %{public}s", want.GetAction().data());
72         return true;
73     }
74 
75     return false;
76 }
77 
ImplicitStartAbility(AbilityRequest & request,int32_t userId)78 int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId)
79 {
80     HILOG_INFO("implicit start ability by type: %{public}d", request.callType);
81     auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
82     CHECK_POINTER_AND_RETURN(sysDialogScheduler, ERR_INVALID_VALUE);
83 
84     std::vector<DialogAppInfo> dialogAppInfos;
85     auto deviceType = OHOS::system::GetDeviceType();
86     HILOG_DEBUG("deviceType is %{public}s", deviceType.c_str());
87     auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, deviceType, false);
88     if (ret != ERR_OK) {
89         HILOG_ERROR("generate ability request by action failed.");
90         return ret;
91     }
92 
93     auto identity = IPCSkeleton::ResetCallingIdentity();
94     auto startAbilityTask = [imp = shared_from_this(), request, userId, identity]
95         (const std::string& bundle, const std::string& abilityName) mutable {
96         HILOG_INFO("implicit start ability call back.");
97 
98         // reset calling indentity
99         IPCSkeleton::SetCallingIdentity(identity);
100 
101         AAFwk::Want targetWant = request.want;
102         targetWant.SetElementName(bundle, abilityName);
103         auto callBack = [imp, targetWant, request, userId]() -> int32_t {
104             return imp->ImplicitStartAbilityInner(targetWant, request, userId);
105         };
106         return imp->CallStartAbilityInner(userId, targetWant, callBack, request.callType);
107     };
108 
109     AAFwk::Want want;
110     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
111     if (dialogAppInfos.size() == 0 && (deviceType == STR_PHONE || deviceType == STR_DEFAULT)) {
112         HILOG_ERROR("implicit query ability infos failed, show tips dialog.");
113         want = sysDialogScheduler->GetTipsDialogWant(request.callerToken);
114         abilityMgr->StartAbility(want);
115         return ERR_IMPLICIT_START_ABILITY_FAIL;
116     } else if (dialogAppInfos.size() == 0 && deviceType != STR_PHONE && deviceType != STR_DEFAULT) {
117         std::vector<DialogAppInfo> dialogAllAppInfos;
118         bool isMoreHapList = true;
119         ret = GenerateAbilityRequestByAction(userId, request, dialogAllAppInfos, deviceType, isMoreHapList);
120         if (ret != ERR_OK) {
121             HILOG_ERROR("generate ability request by action failed.");
122             return ret;
123         }
124         if (dialogAllAppInfos.size() == 0) {
125             Want dialogWant = sysDialogScheduler->GetTipsDialogWant(request.callerToken);
126             abilityMgr->StartAbility(dialogWant);
127             return ERR_IMPLICIT_START_ABILITY_FAIL;
128         }
129         want = sysDialogScheduler->GetPcSelectorDialogWant(dialogAllAppInfos, request.want,
130             TYPE_ONLY_MATCH_WILDCARD, userId, request.callerToken);
131         ret = abilityMgr->StartAbility(want, request.callerToken);
132         // reset calling indentity
133         IPCSkeleton::SetCallingIdentity(identity);
134         return ret;
135     }
136 
137     //There is a default opening method add Only one application supports
138     bool defaultPicker = false;
139     defaultPicker = request.want.GetBoolParam(SHOW_DEFAULT_PICKER_FLAG, defaultPicker);
140     if (dialogAppInfos.size() == 1 && (!defaultPicker || deviceType == STR_PHONE || deviceType == STR_DEFAULT)) {
141         auto info = dialogAppInfos.front();
142         HILOG_INFO("ImplicitQueryInfos success, target ability: %{public}s", info.abilityName.data());
143         return IN_PROCESS_CALL(startAbilityTask(info.bundleName, info.abilityName));
144     }
145 
146     if (deviceType == STR_PHONE || deviceType == STR_DEFAULT) {
147         HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose.");
148         want = sysDialogScheduler->GetSelectorDialogWant(dialogAppInfos, request.want, request.callerToken);
149         ret = abilityMgr->StartAbilityAsCaller(want, request.callerToken);
150         // reset calling indentity
151         IPCSkeleton::SetCallingIdentity(identity);
152         return ret;
153     }
154 
155     HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose in pc.");
156     auto type = request.want.GetType();
157     want = sysDialogScheduler->GetPcSelectorDialogWant(dialogAppInfos, request.want, type, userId, request.callerToken);
158     ret = abilityMgr->StartAbilityAsCaller(want, request.callerToken);
159     // reset calling indentity
160     IPCSkeleton::SetCallingIdentity(identity);
161     return ret;
162 }
163 
GenerateAbilityRequestByAction(int32_t userId,AbilityRequest & request,std::vector<DialogAppInfo> & dialogAppInfos,std::string & deviceType,bool isMoreHapList)164 int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId,
165     AbilityRequest &request, std::vector<DialogAppInfo> &dialogAppInfos, std::string &deviceType, bool isMoreHapList)
166 {
167     HILOG_DEBUG("%{public}s", __func__);
168     // get abilityinfos from bms
169     auto bms = GetBundleManager();
170     CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
171     auto abilityInfoFlag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT
172         | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL_URI;
173     std::vector<AppExecFwk::AbilityInfo> abilityInfos;
174     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
175     bool withDefault = false;
176     withDefault = request.want.GetBoolParam(SHOW_DEFAULT_PICKER_FLAG, withDefault) ? false : true;
177     IN_PROCESS_CALL_WITHOUT_RET(bms->ImplicitQueryInfos(
178         request.want, abilityInfoFlag, userId, withDefault, abilityInfos, extensionInfos));
179 
180     HILOG_INFO("ImplicitQueryInfos, abilityInfo size : %{public}zu, extensionInfos size: %{public}zu",
181         abilityInfos.size(), extensionInfos.size());
182 
183     if (abilityInfos.size() + extensionInfos.size() > 1) {
184         HILOG_INFO("More than one target application, filter by erms");
185         bool ret = FilterAbilityList(request.want, abilityInfos, extensionInfos, userId);
186         if (!ret) {
187             HILOG_ERROR("FilterAbilityList failed");
188         }
189     }
190 
191     auto isExtension = request.callType == AbilityCallType::START_EXTENSION_TYPE;
192 
193     Want implicitwant;
194     implicitwant.SetAction(request.want.GetAction());
195     implicitwant.SetType(TYPE_ONLY_MATCH_WILDCARD);
196     std::vector<AppExecFwk::AbilityInfo> implicitAbilityInfos;
197     std::vector<AppExecFwk::ExtensionAbilityInfo> implicitExtensionInfos;
198     std::vector<std::string> infoNames;
199     if (deviceType != STR_PHONE && deviceType != STR_DEFAULT) {
200         IN_PROCESS_CALL_WITHOUT_RET(bms->ImplicitQueryInfos(implicitwant, abilityInfoFlag, userId,
201             withDefault, implicitAbilityInfos, implicitExtensionInfos));
202         if (implicitAbilityInfos.size() != 0 && request.want.GetType() != TYPE_ONLY_MATCH_WILDCARD) {
203             for (auto implicitAbilityInfo : implicitAbilityInfos) {
204                 infoNames.emplace_back(implicitAbilityInfo.bundleName + "#" +
205                     implicitAbilityInfo.moduleName + "#" + implicitAbilityInfo.name);
206             }
207         }
208     }
209     for (const auto &info : abilityInfos) {
210         if (isExtension && info.type != AbilityType::EXTENSION) {
211             continue;
212         }
213         if (deviceType != STR_PHONE && deviceType != STR_DEFAULT) {
214             auto isDefaultFlag = false;
215             if (withDefault) {
216                 auto defaultMgr = GetDefaultAppProxy();
217                 AppExecFwk::BundleInfo bundleInfo;
218                 ErrCode ret =
219                     IN_PROCESS_CALL(defaultMgr->GetDefaultApplication(userId, request.want.GetType(), bundleInfo));
220                 if (ret == ERR_OK) {
221                     if (bundleInfo.abilityInfos.size() == 1) {
222                         HILOG_INFO("find default ability.");
223                         isDefaultFlag = true;
224                     } else if (bundleInfo.extensionInfos.size() == 1) {
225                         HILOG_INFO("find default extension.");
226                         isDefaultFlag = true;
227                     } else {
228                         HILOG_INFO("GetDefaultApplication failed.");
229                     }
230                 }
231             }
232             if (!isMoreHapList && !isDefaultFlag) {
233                 if (std::find(infoNames.begin(), infoNames.end(),
234                     (info.bundleName + "#" + info.moduleName + "#" + info.name)) != infoNames.end()) {
235                     continue;
236                 }
237             }
238         }
239 
240         DialogAppInfo dialogAppInfo;
241         dialogAppInfo.abilityName = info.name;
242         dialogAppInfo.bundleName = info.bundleName;
243         dialogAppInfo.moduleName = info.moduleName;
244         dialogAppInfo.iconId = info.iconId;
245         dialogAppInfo.labelId = info.labelId;
246         dialogAppInfos.emplace_back(dialogAppInfo);
247     }
248 
249     for (const auto &info : extensionInfos) {
250         if (!isExtension || !CheckImplicitStartExtensionIsValid(request, info)) {
251             continue;
252         }
253         DialogAppInfo dialogAppInfo;
254         dialogAppInfo.abilityName = info.name;
255         dialogAppInfo.bundleName = info.bundleName;
256         dialogAppInfo.iconId = info.iconId;
257         dialogAppInfo.labelId = info.labelId;
258         dialogAppInfos.emplace_back(dialogAppInfo);
259     }
260 
261     return ERR_OK;
262 }
263 
CheckImplicitStartExtensionIsValid(const AbilityRequest & request,const AppExecFwk::ExtensionAbilityInfo & extensionInfo)264 bool ImplicitStartProcessor::CheckImplicitStartExtensionIsValid(const AbilityRequest &request,
265     const AppExecFwk::ExtensionAbilityInfo &extensionInfo)
266 {
267     if (!request.want.GetElement().GetBundleName().empty()) {
268         return true;
269     }
270     HILOG_DEBUG("ImplicitStartExtension type: %{public}d.", static_cast<int32_t>(extensionInfo.type));
271     if (extensionWhiteList.find(extensionInfo.type) == extensionWhiteList.end()) {
272         HILOG_ERROR("The extension without UI is not allowed ImplicitStart");
273         return false;
274     }
275     return true;
276 }
277 
ImplicitStartAbilityInner(const Want & targetWant,const AbilityRequest & request,int32_t userId)278 int32_t ImplicitStartProcessor::ImplicitStartAbilityInner(const Want &targetWant,
279     const AbilityRequest &request, int32_t userId)
280 {
281     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
282     CHECK_POINTER_AND_RETURN(abilityMgr, ERR_INVALID_VALUE);
283 
284     int32_t result = ERR_OK;
285     switch (request.callType) {
286         case AbilityCallType::START_OPTIONS_TYPE: {
287             StartOptions startOptions;
288             auto displayId = targetWant.GetIntParam(Want::PARAM_RESV_DISPLAY_ID, 0);
289             auto windowMode = targetWant.GetIntParam(Want::PARAM_RESV_WINDOW_MODE, 0);
290             startOptions.SetDisplayID(static_cast<int32_t>(displayId));
291             startOptions.SetWindowMode(static_cast<int32_t>(windowMode));
292             result = abilityMgr->StartAbility(
293                 targetWant, startOptions, request.callerToken, userId, request.requestCode);
294             break;
295         }
296         case AbilityCallType::START_SETTINGS_TYPE: {
297             CHECK_POINTER_AND_RETURN(request.startSetting, ERR_INVALID_VALUE);
298             result = abilityMgr->StartAbility(
299                 targetWant, *request.startSetting, request.callerToken, userId, request.requestCode);
300             break;
301         }
302         case AbilityCallType::START_EXTENSION_TYPE:
303             result = abilityMgr->StartExtensionAbility(
304                 targetWant, request.callerToken, userId, request.extensionType);
305             break;
306         default:
307             result = abilityMgr->StartAbilityWrap(
308                 targetWant, request.callerToken, request.requestCode, userId);
309             break;
310     }
311 
312     return result;
313 }
314 
CallStartAbilityInner(int32_t userId,const Want & want,const StartAbilityClosure & callBack,const AbilityCallType & callType)315 int ImplicitStartProcessor::CallStartAbilityInner(int32_t userId,
316     const Want &want, const StartAbilityClosure &callBack, const AbilityCallType &callType)
317 {
318     EventInfo eventInfo;
319     eventInfo.userId = userId;
320     eventInfo.bundleName = want.GetElement().GetBundleName();
321     eventInfo.moduleName = want.GetElement().GetModuleName();
322     eventInfo.abilityName = want.GetElement().GetAbilityName();
323 
324     if (callType == AbilityCallType::INVALID_TYPE) {
325         EventReport::SendAbilityEvent(EventName::START_ABILITY, HiSysEventType::BEHAVIOR, eventInfo);
326     }
327 
328     HILOG_INFO("ability:%{public}s, bundle:%{public}s", eventInfo.abilityName.c_str(), eventInfo.bundleName.c_str());
329 
330     auto ret = callBack();
331     if (ret != ERR_OK) {
332         eventInfo.errCode = ret;
333         if (callType == AbilityCallType::INVALID_TYPE) {
334             EventReport::SendAbilityEvent(EventName::START_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo);
335         }
336     }
337     return ret;
338 }
339 
GetBundleManager()340 sptr<AppExecFwk::IBundleMgr> ImplicitStartProcessor::GetBundleManager()
341 {
342     if (iBundleManager_ == nullptr) {
343         iBundleManager_ = AbilityUtil::GetBundleManager();
344     }
345     return iBundleManager_;
346 }
347 
GetDefaultAppProxy()348 sptr<AppExecFwk::IDefaultApp> ImplicitStartProcessor::GetDefaultAppProxy()
349 {
350     auto bundleMgr = GetBundleManager();
351     auto defaultAppProxy = bundleMgr->GetDefaultAppProxy();
352     if (defaultAppProxy == nullptr) {
353         HILOG_ERROR("GetDefaultAppProxy failed.");
354         return nullptr;
355     }
356     return defaultAppProxy;
357 }
358 
FilterAbilityList(const Want & want,std::vector<AppExecFwk::AbilityInfo> & abilityInfos,std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos,int32_t userId)359 bool ImplicitStartProcessor::FilterAbilityList(const Want &want, std::vector<AppExecFwk::AbilityInfo> &abilityInfos,
360     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos, int32_t userId)
361 {
362 #ifdef SUPPORT_ERMS
363     ErmsCallerInfo callerInfo;
364     GetEcologicalCallerInfo(want, callerInfo, userId);
365     int ret = IN_PROCESS_CALL(EcologicalRuleMgrServiceClient::GetInstance()->EvaluateResolveInfos(want, callerInfo, 0,
366         abilityInfos, extensionInfos));
367 #else
368     auto erms = AbilityUtil::CheckEcologicalRuleMgr();
369     if (!erms) {
370         HILOG_ERROR("get ecological rule mgr failed.");
371         return false;
372     }
373 
374     ErmsCallerInfo callerInfo;
375     int ret = IN_PROCESS_CALL(erms->EvaluateResolveInfos(want, callerInfo, 0, abilityInfos, extensionInfos));
376 #endif
377     if (ret != ERR_OK) {
378         HILOG_ERROR("Failed to evaluate resolve infos from erms.");
379         return false;
380     }
381     return true;
382 }
383 
384 #ifdef SUPPORT_ERMS
GetEcologicalCallerInfo(const Want & want,ErmsCallerInfo & callerInfo,int32_t userId)385 void ImplicitStartProcessor::GetEcologicalCallerInfo(const Want &want, ErmsCallerInfo &callerInfo, int32_t userId)
386 {
387     callerInfo.packageName = want.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
388     callerInfo.uid = want.GetIntParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
389     callerInfo.pid = want.GetIntParam(Want::PARAM_RESV_CALLER_PID, IPCSkeleton::GetCallingPid());
390     callerInfo.targetAppType = TYPE_HARMONY_INVALID;
391     callerInfo.callerAppType = TYPE_HARMONY_INVALID;
392 
393     auto bms = AbilityUtil::GetBundleManager();
394     if (!bms) {
395         HILOG_ERROR("GetBundleManager failed");
396         return;
397     }
398 
399     std::string targetBundleName = want.GetBundle();
400     AppExecFwk::ApplicationInfo targetAppInfo;
401     bool getTargetResult = IN_PROCESS_CALL(bms->GetApplicationInfo(targetBundleName,
402         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, targetAppInfo));
403     if (!getTargetResult) {
404         HILOG_ERROR("Get targetAppInfo failed.");
405     } else if (targetAppInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE) {
406         HILOG_DEBUG("the target type  is atomic service");
407         callerInfo.targetAppType = TYPE_HARMONY_SERVICE;
408     } else if (targetAppInfo.bundleType == AppExecFwk::BundleType::APP) {
409         HILOG_DEBUG("the target type is app");
410         callerInfo.targetAppType = TYPE_HARMONY_APP;
411     } else {
412         HILOG_DEBUG("the target type is invalid type");
413     }
414 
415     std::string callerBundleName;
416     ErrCode err = IN_PROCESS_CALL(bms->GetNameForUid(callerInfo.uid, callerBundleName));
417     if (err != ERR_OK) {
418         HILOG_ERROR("Get callerBundleName failed.");
419         return;
420     }
421     AppExecFwk::ApplicationInfo callerAppInfo;
422     bool getCallerResult = IN_PROCESS_CALL(bms->GetApplicationInfo(callerBundleName,
423         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, callerAppInfo));
424     if (!getCallerResult) {
425         HILOG_DEBUG("Get callerAppInfo failed.");
426     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE) {
427         HILOG_DEBUG("the caller type  is atomic service");
428         callerInfo.callerAppType = TYPE_HARMONY_SERVICE;
429     } else if (callerAppInfo.bundleType == AppExecFwk::BundleType::APP) {
430         HILOG_DEBUG("the caller type is app");
431         callerInfo.callerAppType = TYPE_HARMONY_APP;
432     } else {
433         HILOG_DEBUG("the caller type is invalid type");
434     }
435 }
436 #endif
437 }  // namespace AAFwk
438 }  // namespace OHOS