• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "ability_manager_service.h"
18 #include "ability_util.h"
19 #include "errors.h"
20 #include "event_report.h"
21 #include "hilog_wrapper.h"
22 #include "in_process_call_wrapper.h"
23 
24 namespace OHOS {
25 namespace AAFwk {
26 const std::string BLACK_ACTION_SELECT_DATA = "ohos.want.action.select";
27 
28 const std::vector<std::string> ImplicitStartProcessor::blackList = {
29     std::vector<std::string>::value_type(BLACK_ACTION_SELECT_DATA),
30 };
31 
32 const std::unordered_set<AppExecFwk::ExtensionAbilityType> ImplicitStartProcessor::extensionWhiteList = {
33     AppExecFwk::ExtensionAbilityType::FORM,
34     AppExecFwk::ExtensionAbilityType::INPUTMETHOD,
35     AppExecFwk::ExtensionAbilityType::WALLPAPER,
36     AppExecFwk::ExtensionAbilityType::WINDOW,
37     AppExecFwk::ExtensionAbilityType::THUMBNAIL,
38     AppExecFwk::ExtensionAbilityType::PREVIEW
39 };
40 
IsImplicitStartAction(const Want & want)41 bool ImplicitStartProcessor::IsImplicitStartAction(const Want &want)
42 {
43     auto element = want.GetElement();
44     if (!element.GetAbilityName().empty()) {
45         return false;
46     }
47 
48     if (std::find(blackList.begin(), blackList.end(), want.GetAction()) == blackList.end()) {
49         HILOG_INFO("implicit start, the action is %{public}s", want.GetAction().data());
50         return true;
51     }
52 
53     return false;
54 }
55 
ImplicitStartAbility(AbilityRequest & request,int32_t userId)56 int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId)
57 {
58     HILOG_INFO("implicit start ability by type: %{public}d", request.callType);
59 
60     auto sysDialogScheduler = DelayedSingleton<SystemDialogScheduler>::GetInstance();
61     CHECK_POINTER_AND_RETURN(sysDialogScheduler, ERR_INVALID_VALUE);
62 
63     std::vector<DialogAppInfo> dialogAppInfos;
64     auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos);
65     if (ret != ERR_OK) {
66         HILOG_ERROR("generate ability request by action failed.");
67         return ret;
68     }
69 
70     auto identity = IPCSkeleton::ResetCallingIdentity();
71     auto startAbilityTask = [imp = shared_from_this(), request, userId, identity]
72         (const std::string& bundle, const std::string& abilityName) mutable {
73         HILOG_INFO("implicit start ability call back.");
74 
75         // reset calling indentity
76         IPCSkeleton::SetCallingIdentity(identity);
77 
78         AAFwk::Want targetWant = request.want;
79         targetWant.SetElementName(bundle, abilityName);
80         auto callBack = [imp, targetWant, request, userId]() -> int32_t {
81             return imp->ImplicitStartAbilityInner(targetWant, request, userId);
82         };
83         return imp->CallStartAbilityInner(userId, targetWant, callBack, request.callType);
84     };
85     if (dialogAppInfos.size() == 0) {
86         HILOG_ERROR("implicit query ability infos failed, show tips dialog.");
87         Want want = sysDialogScheduler->GetTipsDialogWant();
88         auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
89         abilityMgr->StartAbility(want);
90         return ERR_IMPLICIT_START_ABILITY_FAIL;
91     }
92 
93     if (dialogAppInfos.size() == 1) {
94         auto info = dialogAppInfos.front();
95         HILOG_INFO("ImplicitQueryInfos success, target ability: %{public}s", info.abilityName.data());
96         return IN_PROCESS_CALL(startAbilityTask(info.bundleName, info.abilityName));
97     }
98 
99     HILOG_INFO("ImplicitQueryInfos success, Multiple apps to choose.");
100     Want want = sysDialogScheduler->GetSelectorDialogWant(dialogAppInfos, request.want);
101     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
102     // reset calling indentity
103     IPCSkeleton::SetCallingIdentity(identity);
104     return abilityMgr->StartAbility(want);
105 }
106 
GenerateAbilityRequestByAction(int32_t userId,AbilityRequest & request,std::vector<DialogAppInfo> & dialogAppInfos)107 int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId,
108     AbilityRequest &request, std::vector<DialogAppInfo> &dialogAppInfos)
109 {
110     HILOG_DEBUG("%{public}s", __func__);
111     // get abilityinfos from bms
112     auto bms = GetBundleManager();
113     CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
114     auto abilityInfoFlag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT;
115     std::vector<AppExecFwk::AbilityInfo> abilityInfos;
116     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
117     IN_PROCESS_CALL_WITHOUT_RET(bms->ImplicitQueryInfos(
118         request.want, abilityInfoFlag, userId, abilityInfos, extensionInfos));
119 
120     HILOG_INFO("ImplicitQueryInfos, abilityInfo size : %{public}zu, extensionInfos size: %{public}zu",
121         abilityInfos.size(), extensionInfos.size());
122 
123     auto isExtension = request.callType == AbilityCallType::START_EXTENSION_TYPE;
124 
125     for (const auto &info : abilityInfos) {
126         if (isExtension && info.type != AbilityType::EXTENSION) {
127             continue;
128         }
129         DialogAppInfo dialogAppInfo;
130         dialogAppInfo.abilityName = info.name;
131         dialogAppInfo.bundleName = info.bundleName;
132         dialogAppInfo.moduleName = info.moduleName;
133         dialogAppInfo.iconId = info.iconId;
134         dialogAppInfo.labelId = info.labelId;
135         dialogAppInfos.emplace_back(dialogAppInfo);
136     }
137 
138     for (const auto &info : extensionInfos) {
139         if (!isExtension || !CheckImplicitStartExtensionIsValid(request, info)) {
140             continue;
141         }
142         DialogAppInfo dialogAppInfo;
143         dialogAppInfo.abilityName = info.name;
144         dialogAppInfo.bundleName = info.bundleName;
145         dialogAppInfo.iconId = info.iconId;
146         dialogAppInfo.labelId = info.labelId;
147         dialogAppInfos.emplace_back(dialogAppInfo);
148     }
149 
150     return ERR_OK;
151 }
152 
CheckImplicitStartExtensionIsValid(const AbilityRequest & request,const AppExecFwk::ExtensionAbilityInfo & extensionInfo)153 bool ImplicitStartProcessor::CheckImplicitStartExtensionIsValid(const AbilityRequest &request,
154     const AppExecFwk::ExtensionAbilityInfo &extensionInfo)
155 {
156     if (!request.want.GetElement().GetBundleName().empty()) {
157         return true;
158     }
159     HILOG_DEBUG("ImplicitStartExtension type: %{public}d.", static_cast<int32_t>(extensionInfo.type));
160     if (extensionWhiteList.find(extensionInfo.type) == extensionWhiteList.end()) {
161         HILOG_ERROR("The extension without UI is not allowed ImplicitStart");
162         return false;
163     }
164     return true;
165 }
166 
ImplicitStartAbilityInner(const Want & targetWant,const AbilityRequest & request,int32_t userId)167 int32_t ImplicitStartProcessor::ImplicitStartAbilityInner(const Want &targetWant,
168     const AbilityRequest &request, int32_t userId)
169 {
170     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
171     CHECK_POINTER_AND_RETURN(abilityMgr, ERR_INVALID_VALUE);
172 
173     int32_t result = ERR_OK;
174     switch (request.callType) {
175         case AbilityCallType::START_OPTIONS_TYPE: {
176             StartOptions startOptions;
177             auto displayId = targetWant.GetIntParam(Want::PARAM_RESV_DISPLAY_ID, 0);
178             auto windowMode = targetWant.GetIntParam(Want::PARAM_RESV_WINDOW_MODE, 0);
179             startOptions.SetDisplayID(static_cast<int32_t>(displayId));
180             startOptions.SetWindowMode(static_cast<int32_t>(windowMode));
181             result = abilityMgr->StartAbility(
182                 targetWant, startOptions, request.callerToken, userId, request.requestCode);
183             break;
184         }
185         case AbilityCallType::START_SETTINGS_TYPE: {
186             CHECK_POINTER_AND_RETURN(request.startSetting, ERR_INVALID_VALUE);
187             result = abilityMgr->StartAbility(
188                 targetWant, *request.startSetting, request.callerToken, userId, request.requestCode);
189             break;
190         }
191         case AbilityCallType::START_EXTENSION_TYPE:
192             result = abilityMgr->StartExtensionAbility(
193                 targetWant, request.callerToken, userId, request.extensionType);
194             break;
195         default:
196             result = abilityMgr->StartAbilityInner(
197                 targetWant, request.callerToken, request.requestCode, request.callerUid, userId);
198             break;
199     }
200 
201     return result;
202 }
203 
CallStartAbilityInner(int32_t userId,const Want & want,const StartAbilityClosure & callBack,const AbilityCallType & callType)204 int ImplicitStartProcessor::CallStartAbilityInner(int32_t userId,
205     const Want &want, const StartAbilityClosure &callBack, const AbilityCallType &callType)
206 {
207     EventInfo eventInfo;
208     eventInfo.userId = userId;
209     eventInfo.bundleName = want.GetElement().GetBundleName();
210     eventInfo.moduleName = want.GetElement().GetModuleName();
211     eventInfo.abilityName = want.GetElement().GetAbilityName();
212 
213     if (callType == AbilityCallType::INVALID_TYPE) {
214         EventReport::SendAbilityEvent(EventName::START_ABILITY, HiSysEventType::BEHAVIOR, eventInfo);
215     }
216 
217     HILOG_INFO("ability:%{public}s, bundle:%{public}s", eventInfo.abilityName.c_str(), eventInfo.bundleName.c_str());
218 
219     auto ret = callBack();
220     if (ret != ERR_OK) {
221         eventInfo.errCode = ret;
222         if (callType == AbilityCallType::INVALID_TYPE) {
223             EventReport::SendAbilityEvent(EventName::START_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo);
224         }
225     }
226     return ret;
227 }
228 
GetBundleManager()229 sptr<AppExecFwk::IBundleMgr> ImplicitStartProcessor::GetBundleManager()
230 {
231     if (iBundleManager_ == nullptr) {
232         auto bundleObj =
233             OHOS::DelayedSingleton<SaMgrClient>::GetInstance()->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
234         if (bundleObj == nullptr) {
235             HILOG_ERROR("Failed to get bundle manager service.");
236             return nullptr;
237         }
238         iBundleManager_ = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
239     }
240     return iBundleManager_;
241 }
242 }  // namespace AAFwk
243 }  // namespace OHOS