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