• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &paramsInfo, 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 &paramsInfo, 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 &paramsInfo)
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 &paramsInfo)
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