1 /*
2 * Copyright (c) 2021-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
16 #include "want_agent_helper.h"
17
18 #include "ability_runtime_error_util.h"
19 #include "hilog_wrapper.h"
20 #include "want_params_wrapper.h"
21 #include "pending_want.h"
22 #include "want_agent_client.h"
23 #include "want_agent_log_wrapper.h"
24 #include "want_sender_info.h"
25 #include "want_sender_interface.h"
26
27 using namespace OHOS::AAFwk;
28 using namespace OHOS::AppExecFwk;
29 using namespace OHOS::AbilityRuntime;
30 namespace OHOS::AbilityRuntime::WantAgent {
WantAgentHelper()31 WantAgentHelper::WantAgentHelper()
32 {}
33
FlagsTransformer(const std::vector<WantAgentConstant::Flags> & flags)34 unsigned int WantAgentHelper::FlagsTransformer(const std::vector<WantAgentConstant::Flags> &flags)
35 {
36 unsigned int wantFlags = 0;
37 if (flags.empty()) {
38 wantFlags |= static_cast<unsigned int>(FLAG_UPDATE_CURRENT);
39 return wantFlags;
40 }
41
42 for (auto flag : flags) {
43 switch (flag) {
44 case WantAgentConstant::Flags::ONE_TIME_FLAG:
45 wantFlags |= static_cast<unsigned int>(FLAG_ONE_SHOT);
46 break;
47 case WantAgentConstant::Flags::NO_BUILD_FLAG:
48 wantFlags |= static_cast<unsigned int>(FLAG_NO_CREATE);
49 break;
50 case WantAgentConstant::Flags::CANCEL_PRESENT_FLAG:
51 wantFlags |= static_cast<unsigned int>(FLAG_CANCEL_CURRENT);
52 break;
53 case WantAgentConstant::Flags::UPDATE_PRESENT_FLAG:
54 wantFlags |= static_cast<unsigned int>(FLAG_UPDATE_CURRENT);
55 break;
56 case WantAgentConstant::Flags::CONSTANT_FLAG:
57 wantFlags |= static_cast<unsigned int>(FLAG_IMMUTABLE);
58 break;
59 default:
60 WANT_AGENT_LOGE("WantAgentHelper::flags is error.");
61 break;
62 }
63 }
64 return wantFlags;
65 }
66
GetWantAgent(const std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> & context,const WantAgentInfo & paramsInfo,std::shared_ptr<WantAgent> & wantAgent)67 ErrCode WantAgentHelper::GetWantAgent(
68 const std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> &context,
69 const WantAgentInfo ¶msInfo, std::shared_ptr<WantAgent> &wantAgent)
70 {
71 if (context == nullptr) {
72 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent invalid input param.");
73 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
74 }
75
76 std::vector<std::shared_ptr<Want>> wants = paramsInfo.GetWants();
77 if (wants.empty()) {
78 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent invalid input param.");
79 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
80 }
81
82 HILOG_INFO("bundle:%{public}s; ability:%{public}s",
83 wants[0]->GetElement().GetBundleName().c_str(),
84 wants[0]->GetElement().GetAbilityName().c_str());
85
86 unsigned int flags = FlagsTransformer(paramsInfo.GetFlags());
87 if (flags == 0) {
88 WANT_AGENT_LOGE("WantAgentHelper::flags invalid.");
89 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
90 }
91
92 std::shared_ptr<WantParams> extraInfo = paramsInfo.GetExtraInfo();
93 std::shared_ptr<PendingWant> pendingWant = nullptr;
94 int requestCode = paramsInfo.GetRequestCode();
95 WantAgentConstant::OperationType operationType = paramsInfo.GetOperationType();
96 ErrCode result;
97 switch (operationType) {
98 case WantAgentConstant::OperationType::START_ABILITY:
99 result = PendingWant::GetAbility(context, requestCode, wants[0], flags, extraInfo, pendingWant);
100 break;
101 case WantAgentConstant::OperationType::START_ABILITIES:
102 result = PendingWant::GetAbilities(context, requestCode, wants, flags, extraInfo, pendingWant);
103 break;
104 case WantAgentConstant::OperationType::START_SERVICE:
105 result = PendingWant::GetService(context, requestCode, wants[0], flags, pendingWant);
106 break;
107 case WantAgentConstant::OperationType::START_FOREGROUND_SERVICE:
108 result = PendingWant::GetForegroundService(context, requestCode, wants[0], flags, pendingWant);
109 break;
110 case WantAgentConstant::OperationType::SEND_COMMON_EVENT:
111 result = PendingWant::GetCommonEvent(context, requestCode, wants[0], flags, pendingWant);
112 break;
113 default:
114 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent operation type is error.");
115 result = ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
116 break;
117 }
118
119 if (pendingWant == nullptr) {
120 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent the wants does not meet the requirements.");
121 return result;
122 }
123 wantAgent = std::make_shared<WantAgent>(pendingWant);
124 return ERR_OK;
125 }
126
GetWantAgent(const WantAgentInfo & paramsInfo,int32_t userId)127 std::shared_ptr<WantAgent> WantAgentHelper::GetWantAgent(const WantAgentInfo ¶msInfo, int32_t userId)
128 {
129 std::vector<std::shared_ptr<Want>> wants = paramsInfo.GetWants();
130 if (wants.empty()) {
131 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent invalid input param.");
132 return nullptr;
133 }
134
135 std::shared_ptr<Want> want = wants[0];
136 if (want == nullptr) {
137 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent invalid input param.");
138 return nullptr;
139 }
140
141 WantsInfo wantsInfo;
142 wantsInfo.want = *want;
143 wantsInfo.resolvedTypes = want->GetType();
144 if (paramsInfo.GetExtraInfo() != nullptr && !paramsInfo.GetExtraInfo()->IsEmpty()) {
145 wantsInfo.want.SetParams(*paramsInfo.GetExtraInfo());
146 }
147
148 HILOG_INFO("bundle:%{public}s; ability:%{public}s",
149 wantsInfo.want.GetElement().GetBundleName().c_str(),
150 wantsInfo.want.GetElement().GetAbilityName().c_str());
151
152 WantSenderInfo wantSenderInfo;
153 wantSenderInfo.allWants.push_back(wantsInfo);
154 wantSenderInfo.bundleName = want->GetOperation().GetBundleName();
155 wantSenderInfo.flags = FlagsTransformer(paramsInfo.GetFlags());
156 wantSenderInfo.type = static_cast<int32_t>(paramsInfo.GetOperationType());
157 wantSenderInfo.userId = userId;
158 sptr<IWantSender> target = nullptr;
159 WantAgentClient::GetInstance().GetWantSender(wantSenderInfo, nullptr, target);
160 if (target == nullptr) {
161 WANT_AGENT_LOGE("WantAgentHelper::GetWantAgent target is nullptr.");
162 return nullptr;
163 }
164 std::shared_ptr<WantAgent> agent = std::make_shared<WantAgent>(std::make_shared<PendingWant>(target));
165
166 return agent;
167 }
168
GetType(const std::shared_ptr<WantAgent> & agent)169 WantAgentConstant::OperationType WantAgentHelper::GetType(const std::shared_ptr<WantAgent> &agent)
170 {
171 if ((agent == nullptr) || (agent->GetPendingWant() == nullptr)) {
172 return WantAgentConstant::OperationType::UNKNOWN_TYPE;
173 }
174
175 return agent->GetPendingWant()->GetType(agent->GetPendingWant()->GetTarget());
176 }
177
TriggerWantAgent(const std::shared_ptr<WantAgent> & agent,const std::shared_ptr<CompletedCallback> & callback,const TriggerInfo & paramsInfo)178 ErrCode WantAgentHelper::TriggerWantAgent(const std::shared_ptr<WantAgent> &agent,
179 const std::shared_ptr<CompletedCallback> &callback, const TriggerInfo ¶msInfo)
180 {
181 HILOG_INFO("call");
182 if (agent == nullptr) {
183 WANT_AGENT_LOGE("WantAgentHelper::TriggerWantAgent invalid input param.");
184 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
185 }
186 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
187 WantAgentConstant::OperationType type = GetType(agent);
188 sptr<CompletedDispatcher> dispatcher = nullptr;
189 if (callback != nullptr) {
190 dispatcher = new (std::nothrow) CompletedDispatcher(pendingWant, callback, nullptr);
191 }
192 return Send(pendingWant, type, dispatcher, paramsInfo);
193 }
194
Send(const std::shared_ptr<PendingWant> & pendingWant,WantAgentConstant::OperationType type,const sptr<CompletedDispatcher> & callBack,const TriggerInfo & paramsInfo)195 ErrCode WantAgentHelper::Send(const std::shared_ptr<PendingWant> &pendingWant,
196 WantAgentConstant::OperationType type, const sptr<CompletedDispatcher> &callBack, const TriggerInfo ¶msInfo)
197 {
198 HILOG_INFO("call");
199 if (pendingWant == nullptr) {
200 WANT_AGENT_LOGE("WantAgentHelper::Send invalid input param.");
201 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
202 }
203
204 return pendingWant->Send(paramsInfo.GetResultCode(),
205 paramsInfo.GetWant(),
206 callBack,
207 paramsInfo.GetPermission(),
208 paramsInfo.GetExtraInfo(),
209 pendingWant->GetTarget());
210 }
211
Cancel(const std::shared_ptr<WantAgent> & agent)212 ErrCode WantAgentHelper::Cancel(const std::shared_ptr<WantAgent> &agent)
213 {
214 if (agent == nullptr) {
215 WANT_AGENT_LOGE("WantAgentHelper::Cancel WantAgent invalid input param.");
216 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
217 }
218
219 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
220 if (pendingWant == nullptr) {
221 WANT_AGENT_LOGE("WantAgentHelper::Cancel PendingWant invalid input param.");
222 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
223 }
224
225 return pendingWant->Cancel(pendingWant->GetTarget());
226 }
227
IsEquals(const std::shared_ptr<WantAgent> & agent,const std::shared_ptr<WantAgent> & otherAgent)228 ErrCode WantAgentHelper::IsEquals(
229 const std::shared_ptr<WantAgent> &agent, const std::shared_ptr<WantAgent> &otherAgent)
230 {
231 if ((agent == nullptr) && (otherAgent == nullptr)) {
232 return ERR_OK;
233 }
234
235 if ((agent == nullptr) || (otherAgent == nullptr)) {
236 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
237 }
238 return PendingWant::IsEquals(agent->GetPendingWant(), otherAgent->GetPendingWant());
239 }
240
GetBundleName(const std::shared_ptr<WantAgent> & agent,std::string & bundleName)241 ErrCode WantAgentHelper::GetBundleName(const std::shared_ptr<WantAgent> &agent, std::string &bundleName)
242 {
243 WANT_AGENT_LOGD("WantAgentHelper::GetBundleName");
244 if (agent == nullptr) {
245 WANT_AGENT_LOGE("WantAgentHelper::GetBundleName WantAgent invalid input param.");
246 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
247 }
248
249 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
250 if (pendingWant == nullptr) {
251 WANT_AGENT_LOGE("WantAgentHelper::GetBundleName PendingWant invalid input param.");
252 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
253 }
254
255 return pendingWant->GetBundleName(pendingWant->GetTarget(), bundleName);
256 }
257
GetUid(const std::shared_ptr<WantAgent> & agent,int32_t & uid)258 ErrCode WantAgentHelper::GetUid(const std::shared_ptr<WantAgent> &agent, int32_t &uid)
259 {
260 if (agent == nullptr) {
261 WANT_AGENT_LOGE("WantAgentHelper::GetUid WantAgent invalid input param.");
262 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
263 }
264
265 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
266 if (pendingWant == nullptr) {
267 WANT_AGENT_LOGE("WantAgentHelper::GetUid PendingWant invalid input param.");
268 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
269 }
270
271 return pendingWant->GetUid(pendingWant->GetTarget(), uid);
272 }
273
GetWant(const std::shared_ptr<WantAgent> & agent)274 std::shared_ptr<Want> WantAgentHelper::GetWant(const std::shared_ptr<WantAgent> &agent)
275 {
276 if (agent == nullptr) {
277 WANT_AGENT_LOGE("WantAgentHelper::GetWant WantAgent invalid input param.");
278 return nullptr;
279 }
280
281 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
282 if (pendingWant == nullptr) {
283 WANT_AGENT_LOGE("WantAgentHelper::GetWant PendingWant invalid input param.");
284 return nullptr;
285 }
286
287 return pendingWant->GetWant(pendingWant->GetTarget());
288 }
289
RegisterCancelListener(const std::shared_ptr<CancelListener> & cancelListener,const std::shared_ptr<WantAgent> & agent)290 void WantAgentHelper::RegisterCancelListener(
291 const std::shared_ptr<CancelListener> &cancelListener, const std::shared_ptr<WantAgent> &agent)
292 {
293 if (agent == nullptr) {
294 WANT_AGENT_LOGE("WantAgentHelper::RegisterCancelListener WantAgent invalid input param.");
295 return;
296 }
297
298 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
299 if (pendingWant == nullptr) {
300 WANT_AGENT_LOGE("WantAgentHelper::RegisterCancelListener PendingWant invalid input param.");
301 return;
302 }
303
304 pendingWant->RegisterCancelListener(cancelListener, pendingWant->GetTarget());
305 }
306
UnregisterCancelListener(const std::shared_ptr<CancelListener> & cancelListener,const std::shared_ptr<WantAgent> & agent)307 void WantAgentHelper::UnregisterCancelListener(
308 const std::shared_ptr<CancelListener> &cancelListener, const std::shared_ptr<WantAgent> &agent)
309 {
310 if (agent == nullptr) {
311 WANT_AGENT_LOGE("WantAgentHelper::UnregisterCancelListener WantAgent invalid input param.");
312 return;
313 }
314
315 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
316 if (pendingWant == nullptr) {
317 WANT_AGENT_LOGE("WantAgentHelper::UnregisterCancelListener PendingWant invalid input param.");
318 return;
319 }
320
321 pendingWant->UnregisterCancelListener(cancelListener, pendingWant->GetTarget());
322 }
323
ToString(const std::shared_ptr<WantAgent> & agent)324 std::string WantAgentHelper::ToString(const std::shared_ptr<WantAgent> &agent)
325 {
326 if (agent == nullptr) {
327 WANT_AGENT_LOGE("WantAgentHelper::ToString WantAgent invalid input param.");
328 return "";
329 }
330
331 std::shared_ptr<PendingWant> pendingWant = agent->GetPendingWant();
332 if (pendingWant == nullptr) {
333 WANT_AGENT_LOGE("WantAgentHelper::ToString PendingWant invalid input param.");
334 return "";
335 }
336
337 std::shared_ptr<WantSenderInfo> info = pendingWant->GetWantSenderInfo(pendingWant->GetTarget());
338 if (info == nullptr) {
339 WANT_AGENT_LOGE("WantAgentHelper::ToString WantSenderInfo invalid input param.");
340 return "";
341 }
342 nlohmann::json jsonObject;
343 jsonObject["requestCode"] = (*info.get()).requestCode;
344 jsonObject["operationType"] = (*info.get()).type;
345 jsonObject["flags"] = (*info.get()).flags;
346
347 nlohmann::json wants = nlohmann::json::array();
348 for (auto &wantInfo : (*info.get()).allWants) {
349 wants.emplace_back(wantInfo.want.ToString());
350 }
351 jsonObject["wants"] = wants;
352
353 if ((*info.get()).allWants.size() > 0) {
354 nlohmann::json paramsObj;
355 AAFwk::WantParamWrapper wWrapper((*info.get()).allWants[0].want.GetParams());
356 paramsObj["extraInfoValue"] = wWrapper.ToString();
357 jsonObject["extraInfo"] = paramsObj;
358 }
359
360 return jsonObject.dump();
361 }
362
FromString(const std::string & jsonString)363 std::shared_ptr<WantAgent> WantAgentHelper::FromString(const std::string &jsonString)
364 {
365 if (jsonString.empty()) {
366 return nullptr;
367 }
368 nlohmann::json jsonObject = nlohmann::json::parse(jsonString);
369
370 int requestCode = -1;
371 if (jsonObject.contains("requestCode") && jsonObject["requestCode"].is_number_integer()) {
372 requestCode = jsonObject.at("requestCode").get<int>();
373 }
374
375 WantAgentConstant::OperationType operationType = WantAgentConstant::OperationType::UNKNOWN_TYPE;
376 if (jsonObject.contains("operationType") && jsonObject["operationType"].is_number_integer()) {
377 operationType = static_cast<WantAgentConstant::OperationType>(jsonObject.at("operationType").get<int>());
378 }
379
380 std::vector<WantAgentConstant::Flags> flagsVec = ParseFlags(jsonObject);
381
382 std::vector<std::shared_ptr<AAFwk::Want>> wants = {};
383 if (jsonObject.contains("wants") && jsonObject["wants"].is_array()) {
384 for (auto &wantObj : jsonObject.at("wants")) {
385 if (wantObj.is_string()) {
386 auto wantString = wantObj.get<std::string>();
387 wants.emplace_back(std::make_shared<AAFwk::Want>(*Want::FromString(wantString)));
388 }
389 }
390 }
391
392 std::shared_ptr<AAFwk::WantParams> extraInfo = nullptr;
393 if (jsonObject.contains("extraInfo") && jsonObject["extraInfo"].is_object()) {
394 auto extraInfoObj = jsonObject.at("extraInfo");
395 if (extraInfoObj.contains("extraInfoValue") && extraInfoObj["extraInfoValue"].is_string()) {
396 auto pwWrapper = AAFwk::WantParamWrapper::Parse(extraInfoObj.at("extraInfoValue").get<std::string>());
397 AAFwk::WantParams params;
398 if (pwWrapper->GetValue(params) == ERR_OK) {
399 extraInfo = std::make_shared<AAFwk::WantParams>(params);
400 }
401 }
402 }
403 WantAgentInfo info(requestCode, operationType, flagsVec, wants, extraInfo);
404
405 return GetWantAgent(info);
406 }
407
ParseFlags(nlohmann::json jsonObject)408 std::vector<WantAgentConstant::Flags> WantAgentHelper::ParseFlags(nlohmann::json jsonObject)
409 {
410 int flags = -1;
411 std::vector<WantAgentConstant::Flags> flagsVec = {};
412 if (jsonObject.contains("flags") && jsonObject.at("flags").is_number_integer()) {
413 flags = jsonObject.at("flags").get<int>();
414 }
415
416 if (flags < 0) {
417 return flagsVec;
418 }
419
420 if (static_cast<uint32_t>(flags) & static_cast<uint32_t>(FLAG_ONE_SHOT)) {
421 flagsVec.emplace_back(WantAgentConstant::Flags::ONE_TIME_FLAG);
422 }
423 if (static_cast<uint32_t>(flags) & static_cast<uint32_t>(FLAG_NO_CREATE)) {
424 flagsVec.emplace_back(WantAgentConstant::Flags::NO_BUILD_FLAG);
425 }
426 if (static_cast<uint32_t>(flags) & static_cast<uint32_t>(FLAG_CANCEL_CURRENT)) {
427 flagsVec.emplace_back(WantAgentConstant::Flags::CANCEL_PRESENT_FLAG);
428 }
429 if (static_cast<uint32_t>(flags) & static_cast<uint32_t>(FLAG_UPDATE_CURRENT)) {
430 flagsVec.emplace_back(WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
431 }
432 if (static_cast<uint32_t>(flags) & static_cast<uint32_t>(FLAG_IMMUTABLE)) {
433 flagsVec.emplace_back(WantAgentConstant::Flags::CONSTANT_FLAG);
434 }
435
436 return flagsVec;
437 }
438
GetType(const std::shared_ptr<WantAgent> & agent,int32_t & operType)439 ErrCode WantAgentHelper::GetType(const std::shared_ptr<WantAgent> &agent, int32_t &operType)
440 {
441 if ((agent == nullptr) || (agent->GetPendingWant() == nullptr)) {
442 WANT_AGENT_LOGE("WantAgent or PendingWant invalid input param.");
443 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_WANTAGENT;
444 }
445
446 return agent->GetPendingWant()->GetType(agent->GetPendingWant()->GetTarget(), operType);
447 }
448
GetWant(const std::shared_ptr<WantAgent> & agent,std::shared_ptr<AAFwk::Want> & want)449 ErrCode WantAgentHelper::GetWant(const std::shared_ptr<WantAgent> &agent, std::shared_ptr<AAFwk::Want> &want)
450 {
451 if ((agent == nullptr) || (agent->GetPendingWant() == nullptr)) {
452 WANT_AGENT_LOGE("WantAgent or PendingWant invalid input param.");
453 return ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_WANTAGENT;
454 }
455
456 return agent->GetPendingWant()->GetWant(agent->GetPendingWant()->GetTarget(), want);
457 }
458 } // namespace OHOS::AbilityRuntime::WantAgent
459