1 /*
2  * Copyright (c) 2021-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 
16 #include "distributed_want.h"
17 
18 #include <algorithm>
19 #include <climits>
20 #include <cstdlib>
21 #include <regex>
22 #include <securec.h>
23 
24 #include "array_wrapper.h"
25 #include "base_obj.h"
26 #include "bool_wrapper.h"
27 #include "byte_wrapper.h"
28 #include "double_wrapper.h"
29 #include "float_wrapper.h"
30 #include "int_wrapper.h"
31 #include "long_wrapper.h"
32 #include "parcel_macro_base.h"
33 #include "remote_object_wrapper.h"
34 #include "short_wrapper.h"
35 #include "string_ex.h"
36 #include "string_wrapper.h"
37 #include "zchar_wrapper.h"
38 
39 #include "distributed_operation_builder.h"
40 #include "distributed_want_params_wrapper.h"
41 #include "dtbschedmgr_log.h"
42 
43 using namespace OHOS::AppExecFwk;
44 using OHOS::AppExecFwk::ElementName;
45 namespace OHOS {
46 namespace DistributedSchedule {
47 namespace {
48 const std::regex NUMBER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$");
49 const std::string TAG = "DistributedWant";
50 const char* TYPE_PROPERTY = "type";
51 };  // namespace
52 const std::string DistributedWant::ACTION_PLAY("action.system.play");
53 const std::string DistributedWant::ACTION_HOME("action.system.home");
54 
55 const std::string DistributedWant::ENTITY_HOME("entity.system.home");
56 const std::string DistributedWant::ENTITY_VIDEO("entity.system.video");
57 const std::string DistributedWant::FLAG_HOME_INTENT_FROM_SYSTEM("flag.home.intent.from.system");
58 const std::string DistributedWant::ENTITY_MUSIC("entity.app.music");
59 const std::string DistributedWant::ENTITY_EMAIL("entity.app.email");
60 const std::string DistributedWant::ENTITY_CONTACTS("entity.app.contacts");
61 const std::string DistributedWant::ENTITY_MAPS("entity.app.maps");
62 const std::string DistributedWant::ENTITY_BROWSER("entity.app.browser");
63 const std::string DistributedWant::ENTITY_CALENDAR("entity.app.calendar");
64 const std::string DistributedWant::ENTITY_MESSAGING("entity.app.messaging");
65 const std::string DistributedWant::ENTITY_FILES("entity.app.files");
66 const std::string DistributedWant::ENTITY_GALLERY("entity.app.gallery");
67 
68 const std::string DistributedWant::OCT_EQUALSTO("075");   // '='
69 const std::string DistributedWant::OCT_SEMICOLON("073");  // ';'
70 const std::string DistributedWant::MIME_TYPE("mime-type");
71 const std::string DistributedWant::WANT_HEADER("#Intent;");
72 
73 const std::string DistributedWant::PARAM_RESV_WINDOW_MODE("ohos.aafwk.param.windowMode");
74 const std::string DistributedWant::PARAM_RESV_DISPLAY_ID("ohos.aafwk.param.displayId");
75 const std::string DistributedWant::PARAM_RESV_CALLER_TOKEN("ohos.aafwk.param.callerToken");
76 const std::string DistributedWant::PARAM_RESV_CALLER_UID("ohos.aafwk.param.callerUid");
77 const std::string DistributedWant::PARAM_RESV_CALLER_PID("ohos.aafwk.param.callerPid");
78 
DistributedWant()79 DistributedWant::DistributedWant()
80 {}
81 
~DistributedWant()82 DistributedWant::~DistributedWant()
83 {}
84 
DistributedWant(const DistributedWant & other)85 DistributedWant::DistributedWant(const DistributedWant& other)
86 {
87     operation_ = other.operation_;
88     parameters_ = other.parameters_;
89 }
90 
operator =(const DistributedWant & other)91 DistributedWant& DistributedWant::operator=(const DistributedWant& other)
92 {
93     operation_ = other.operation_;
94     parameters_ = other.parameters_;
95     return *this;
96 }
97 
DistributedWant(const AAFwk::Want & want)98 DistributedWant::DistributedWant(const AAFwk::Want& want)
99 {
100     DistributedOperationBuilder builder;
101     builder.WithAbilityName(want.GetElement().GetAbilityName());
102     builder.WithBundleName(want.GetElement().GetBundleName());
103     builder.WithDeviceId(want.GetElement().GetDeviceID());
104     builder.WithAction(want.GetAction());
105     builder.WithEntities(want.GetEntities());
106     builder.WithFlags(want.GetFlags());
107     builder.WithUri(want.GetUri());
108     std::shared_ptr<DistributedOperation> op = builder.build();
109     operation_ = *op;
110     std::map<std::string, sptr<AAFwk::IInterface>> data = want.GetParams().GetParams();
111     for (auto it = data.begin(); it != data.end(); it++) {
112         auto tp = AAFwk::WantParams::GetDataType(it->second);
113         if ((tp == DistributedWantParams::VALUE_TYPE_BOOLEAN) ||
114             (tp == DistributedWantParams::VALUE_TYPE_BYTE) ||
115             (tp == DistributedWantParams::VALUE_TYPE_CHAR) ||
116             (tp == DistributedWantParams::VALUE_TYPE_SHORT) ||
117             (tp == DistributedWantParams::VALUE_TYPE_INT) ||
118             (tp == DistributedWantParams::VALUE_TYPE_LONG) ||
119             (tp == DistributedWantParams::VALUE_TYPE_FLOAT) ||
120             (tp == DistributedWantParams::VALUE_TYPE_DOUBLE) ||
121             (tp == DistributedWantParams::VALUE_TYPE_STRING) ||
122             (tp == DistributedWantParams::VALUE_TYPE_ARRAY) ||
123             (tp == DistributedWantParams::VALUE_TYPE_REMOTE_OBJECT) ||
124             (tp == DistributedWantParams::VALUE_TYPE_WANTPARAMS)) {
125             parameters_.SetParam(it->first, it->second);
126         }
127     }
128 }
129 
ToWant()130 std::shared_ptr<AAFwk::Want> DistributedWant::ToWant()
131 {
132     auto want = std::make_shared<AAFwk::Want>();
133     want->SetFlags(GetFlags());
134     want->SetElement(GetElement());
135     want->SetUri(GetUri());
136     want->SetAction(GetAction());
137     want->SetBundle(GetBundle());
138     want->SetType(GetType());
139     std::vector<std::string> ents = GetEntities();
140     for (auto it = ents.begin(); it != ents.end(); it++) {
141         want->AddEntity(*it);
142     }
143     want->SetParams(parameters_.ToWantParams());
144     return want;
145 }
146 
GetFlags() const147 unsigned int DistributedWant::GetFlags() const
148 {
149     return operation_.GetFlags();
150 }
151 
SetFlags(unsigned int flags)152 DistributedWant& DistributedWant::SetFlags(unsigned int flags)
153 {
154     operation_.SetFlags(flags);
155     return *this;
156 }
157 
AddFlags(unsigned int flags)158 DistributedWant& DistributedWant::AddFlags(unsigned int flags)
159 {
160     operation_.AddFlags(flags);
161     return *this;
162 }
163 
RemoveFlags(unsigned int flags)164 void DistributedWant::RemoveFlags(unsigned int flags)
165 {
166     operation_.RemoveFlags(flags);
167 }
168 
GetElement() const169 OHOS::AppExecFwk::ElementName DistributedWant::GetElement() const
170 {
171     return ElementName(operation_.GetDeviceId(), operation_.GetBundleName(), operation_.GetAbilityName());
172 }
173 
SetElementName(const std::string & bundleName,const std::string & abilityName)174 DistributedWant& DistributedWant::SetElementName(const std::string& bundleName, const std::string& abilityName)
175 {
176     operation_.SetBundleName(bundleName);
177     operation_.SetAbilityName(abilityName);
178     return *this;
179 }
180 
SetElementName(const std::string & deviceId,const std::string & bundleName,const std::string & abilityName)181 DistributedWant& DistributedWant::SetElementName(const std::string& deviceId, const std::string& bundleName,
182                                                  const std::string& abilityName)
183 {
184     operation_.SetDeviceId(deviceId);
185     operation_.SetBundleName(bundleName);
186     operation_.SetAbilityName(abilityName);
187     return *this;
188 }
189 
SetElement(const OHOS::AppExecFwk::ElementName & element)190 DistributedWant& DistributedWant::SetElement(const OHOS::AppExecFwk::ElementName& element)
191 {
192     operation_.SetDeviceId(element.GetDeviceID());
193     operation_.SetBundleName(element.GetBundleName());
194     operation_.SetAbilityName(element.GetAbilityName());
195     return *this;
196 }
197 
GetEntities() const198 const std::vector<std::string>& DistributedWant::GetEntities() const
199 {
200     return operation_.GetEntities();
201 }
202 
AddEntity(const std::string & entity)203 DistributedWant& DistributedWant::AddEntity(const std::string& entity)
204 {
205     operation_.AddEntity(entity);
206     return *this;
207 }
208 
RemoveEntity(const std::string & entity)209 void DistributedWant::RemoveEntity(const std::string& entity)
210 {
211     operation_.RemoveEntity(entity);
212 }
213 
HasEntity(const std::string & entity) const214 bool DistributedWant::HasEntity(const std::string& entity) const
215 {
216     return operation_.HasEntity(entity);
217 }
218 
CountEntities()219 int DistributedWant::CountEntities()
220 {
221     return operation_.CountEntities();
222 }
223 
GetBundle() const224 std::string DistributedWant::GetBundle() const
225 {
226     return operation_.GetBundleName();
227 }
228 
SetBundle(const std::string & bundleName)229 DistributedWant& DistributedWant::SetBundle(const std::string& bundleName)
230 {
231     operation_.SetBundleName(bundleName);
232     return *this;
233 }
234 
GetType() const235 std::string DistributedWant::GetType() const
236 {
237     auto value = parameters_.GetParam(MIME_TYPE);
238     AAFwk::IString* ao = AAFwk::IString::Query(value);
239     if (ao != nullptr) {
240         return AAFwk::String::Unbox(ao);
241     }
242     return std::string();
243 }
244 
SetType(const std::string & type)245 DistributedWant& DistributedWant::SetType(const std::string& type)
246 {
247     sptr<AAFwk::IString> valueObj = AAFwk::String::Parse(type);
248     parameters_.SetParam(MIME_TYPE, valueObj);
249     return *this;
250 }
251 
GetLowerCaseScheme(const Uri & uri)252 Uri DistributedWant::GetLowerCaseScheme(const Uri& uri)
253 {
254     std::string dStrUri = const_cast<Uri&>(uri).ToString();
255     std::string schemeStr = const_cast<Uri&>(uri).GetScheme();
256     if (dStrUri.empty() || schemeStr.empty()) {
257         return uri;
258     }
259 
260     std::string lowSchemeStr = schemeStr;
261     std::transform(lowSchemeStr.begin(), lowSchemeStr.end(), lowSchemeStr.begin(), [](unsigned char c) {
262         return std::tolower(c);
263     });
264 
265     if (schemeStr == lowSchemeStr) {
266         return uri;
267     }
268 
269     std::size_t pos = dStrUri.find_first_of(schemeStr, 0);
270     if (pos != std::string::npos) {
271         dStrUri.replace(pos, schemeStr.length(), lowSchemeStr);
272     }
273 
274     return Uri(dStrUri);
275 }
276 
GetAction() const277 std::string DistributedWant::GetAction() const
278 {
279     return operation_.GetAction();
280 }
281 
SetAction(const std::string & action)282 DistributedWant& DistributedWant::SetAction(const std::string& action)
283 {
284     operation_.SetAction(action);
285     return *this;
286 }
287 
GetScheme() const288 const std::string DistributedWant::GetScheme() const
289 {
290     return operation_.GetUri().GetScheme();
291 }
292 
GetParams() const293 const DistributedWantParams& DistributedWant::GetParams() const
294 {
295     return parameters_;
296 }
297 
SetParams(const DistributedWantParams & wantParams)298 DistributedWant& DistributedWant::SetParams(const DistributedWantParams& wantParams)
299 {
300     parameters_ = wantParams;
301     return *this;
302 }
303 
GetBoolParam(const std::string & key,bool defaultValue) const304 bool DistributedWant::GetBoolParam(const std::string& key, bool defaultValue) const
305 {
306     auto value = parameters_.GetParam(key);
307     AAFwk::IBoolean* bo = AAFwk::IBoolean::Query(value);
308     if (bo != nullptr) {
309         return AAFwk::Boolean::Unbox(bo);
310     }
311     return defaultValue;
312 }
313 
GetBoolArrayParam(const std::string & key) const314 std::vector<bool> DistributedWant::GetBoolArrayParam(const std::string& key) const
315 {
316     std::vector<bool> array;
317     auto value = parameters_.GetParam(key);
318     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
319     if (ao != nullptr && AAFwk::Array::IsBooleanArray(ao)) {
320         auto func = [&](AAFwk::IInterface* object) {
321             if (object != nullptr) {
322                 AAFwk::IBoolean* value = AAFwk::IBoolean::Query(object);
323                 if (value != nullptr) {
324                     array.push_back(AAFwk::Boolean::Unbox(value));
325                 }
326             }
327         };
328         AAFwk::Array::ForEach(ao, func);
329     }
330     return array;
331 }
332 
SetParam(const std::string & key,const sptr<IRemoteObject> & remoteObject)333 DistributedWant& DistributedWant::SetParam(const std::string& key, const sptr<IRemoteObject>& remoteObject)
334 {
335     DistributedWantParams wp;
336     wp.SetParam(TYPE_PROPERTY, AAFwk::String::Box(AAFwk::REMOTE_OBJECT));
337     wp.SetParam(AAFwk::VALUE_PROPERTY, AAFwk::RemoteObjectWrap::Box(remoteObject));
338     parameters_.SetParam(key, DistributedWantParamWrapper::Box(wp));
339     return *this;
340 }
341 
SetParam(const std::string & key,bool value)342 DistributedWant& DistributedWant::SetParam(const std::string& key, bool value)
343 {
344     parameters_.SetParam(key, AAFwk::Boolean::Box(value));
345     return *this;
346 }
347 
SetParam(const std::string & key,const std::vector<bool> & value)348 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<bool>& value)
349 {
350     std::size_t size = value.size();
351     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IBoolean));
352     if (ao != nullptr) {
353         for (std::size_t i = 0; i < size; i++) {
354             ao->Set(i, AAFwk::Boolean::Box(value[i]));
355         }
356         parameters_.SetParam(key, ao);
357     }
358     return *this;
359 }
360 
GetByteParam(const std::string & key,const AAFwk::byte defaultValue) const361 AAFwk::byte DistributedWant::GetByteParam(const std::string& key, const AAFwk::byte defaultValue) const
362 {
363     auto value = parameters_.GetParam(key);
364     AAFwk::IByte* bo = AAFwk::IByte::Query(value);
365     if (bo != nullptr) {
366         return AAFwk::Byte::Unbox(bo);
367     }
368     return defaultValue;
369 }
370 
GetByteArrayParam(const std::string & key) const371 std::vector<AAFwk::byte> DistributedWant::GetByteArrayParam(const std::string& key) const
372 {
373     std::vector<AAFwk::byte> array;
374     auto value = parameters_.GetParam(key);
375     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
376     if (ao != nullptr && AAFwk::Array::IsByteArray(ao)) {
377         auto func = [&](AAFwk::IInterface* object) {
378             if (object != nullptr) {
379                 AAFwk::IByte* value = AAFwk::IByte::Query(object);
380                 if (value != nullptr) {
381                     array.push_back(AAFwk::Byte::Unbox(value));
382                 }
383             }
384         };
385         AAFwk::Array::ForEach(ao, func);
386     }
387     return array;
388 }
389 
SetParam(const std::string & key,AAFwk::byte value)390 DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::byte value)
391 {
392     parameters_.SetParam(key, AAFwk::Byte::Box(value));
393     return *this;
394 }
395 
SetParam(const std::string & key,const std::vector<AAFwk::byte> & value)396 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<AAFwk::byte>& value)
397 {
398     std::size_t size = value.size();
399     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IByte));
400     if (ao == nullptr) {
401         return *this;
402     }
403     for (std::size_t i = 0; i < size; i++) {
404         ao->Set(i, AAFwk::Byte::Box(value[i]));
405     }
406     parameters_.SetParam(key, ao);
407     return *this;
408 }
409 
GetCharParam(const std::string & key,AAFwk::zchar defaultValue) const410 AAFwk::zchar DistributedWant::GetCharParam(const std::string& key, AAFwk::zchar defaultValue) const
411 {
412     auto value = parameters_.GetParam(key);
413     AAFwk::IChar* ao = AAFwk::IChar::Query(value);
414     if (ao != nullptr) {
415         return AAFwk::Char::Unbox(ao);
416     }
417     return defaultValue;
418 }
419 
GetCharArrayParam(const std::string & key) const420 std::vector<AAFwk::zchar> DistributedWant::GetCharArrayParam(const std::string& key) const
421 {
422     std::vector<AAFwk::zchar> array;
423     auto value = parameters_.GetParam(key);
424     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
425     if (ao != nullptr && AAFwk::Array::IsCharArray(ao)) {
426         auto func = [&](AAFwk::IInterface* object) {
427             if (object != nullptr) {
428                 AAFwk::IChar* value = AAFwk::IChar::Query(object);
429                 if (value != nullptr) {
430                     array.push_back(AAFwk::Char::Unbox(value));
431                 }
432             }
433         };
434         AAFwk::Array::ForEach(ao, func);
435     }
436     return array;
437 }
438 
SetParam(const std::string & key,AAFwk::zchar value)439 DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::zchar value)
440 {
441     parameters_.SetParam(key, AAFwk::Char::Box(value));
442     return *this;
443 }
444 
SetParam(const std::string & key,const std::vector<AAFwk::zchar> & value)445 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<AAFwk::zchar>& value)
446 {
447     std::size_t size = value.size();
448     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IChar));
449     if (ao == nullptr) {
450         return *this;
451     }
452     for (std::size_t i = 0; i < size; i++) {
453         ao->Set(i, AAFwk::Char::Box(value[i]));
454     }
455     parameters_.SetParam(key, ao);
456     return *this;
457 }
458 
GetIntParam(const std::string & key,const int defaultValue) const459 int DistributedWant::GetIntParam(const std::string& key, const int defaultValue) const
460 {
461     auto value = parameters_.GetParam(key);
462     AAFwk::IInteger* ao = AAFwk::IInteger::Query(value);
463     if (ao != nullptr) {
464         return AAFwk::Integer::Unbox(ao);
465     }
466     return defaultValue;
467 }
468 
GetIntArrayParam(const std::string & key) const469 std::vector<int> DistributedWant::GetIntArrayParam(const std::string& key) const
470 {
471     std::vector<int> array;
472     auto value = parameters_.GetParam(key);
473     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
474     if (ao != nullptr && AAFwk::Array::IsIntegerArray(ao)) {
475         auto func = [&](AAFwk::IInterface* object) {
476             if (object != nullptr) {
477                 AAFwk::IInteger* value = AAFwk::IInteger::Query(object);
478                 if (value != nullptr) {
479                     array.push_back(AAFwk::Integer::Unbox(value));
480                 }
481             }
482         };
483         AAFwk::Array::ForEach(ao, func);
484     }
485     return array;
486 }
487 
SetParam(const std::string & key,int value)488 DistributedWant& DistributedWant::SetParam(const std::string& key, int value)
489 {
490     parameters_.SetParam(key, AAFwk::Integer::Box(value));
491     return *this;
492 }
493 
SetParam(const std::string & key,const std::vector<int> & value)494 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<int>& value)
495 {
496     std::size_t size = value.size();
497     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IInteger));
498     if (ao == nullptr) {
499         return *this;
500     }
501     for (std::size_t i = 0; i < size; i++) {
502         ao->Set(i, AAFwk::Integer::Box(value[i]));
503     }
504     parameters_.SetParam(key, ao);
505     return *this;
506 }
507 
GetDoubleParam(const std::string & key,double defaultValue) const508 double DistributedWant::GetDoubleParam(const std::string& key, double defaultValue) const
509 {
510     auto value = parameters_.GetParam(key);
511     AAFwk::IDouble* ao = AAFwk::IDouble::Query(value);
512     if (ao != nullptr) {
513         return AAFwk::Double::Unbox(ao);
514     }
515     return defaultValue;
516 }
517 
GetDoubleArrayParam(const std::string & key) const518 std::vector<double> DistributedWant::GetDoubleArrayParam(const std::string& key) const
519 {
520     std::vector<double> array;
521     auto value = parameters_.GetParam(key);
522     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
523     if (ao != nullptr && AAFwk::Array::IsDoubleArray(ao)) {
524         auto func = [&](AAFwk::IInterface* object) {
525             if (object != nullptr) {
526                 AAFwk::IDouble* value = AAFwk::IDouble::Query(object);
527                 if (value != nullptr) {
528                     array.push_back(AAFwk::Double::Unbox(value));
529                 }
530             }
531         };
532         AAFwk::Array::ForEach(ao, func);
533     }
534     return array;
535 }
536 
SetParam(const std::string & key,double value)537 DistributedWant& DistributedWant::SetParam(const std::string& key, double value)
538 {
539     parameters_.SetParam(key, AAFwk::Double::Box(value));
540     return *this;
541 }
542 
SetParam(const std::string & key,const std::vector<double> & value)543 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<double>& value)
544 {
545     std::size_t size = value.size();
546     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IDouble));
547     if (ao == nullptr) {
548         return *this;
549     }
550     for (std::size_t i = 0; i < size; i++) {
551         ao->Set(i, AAFwk::Double::Box(value[i]));
552     }
553     parameters_.SetParam(key, ao);
554     return *this;
555 }
556 
GetFloatParam(const std::string & key,float defaultValue) const557 float DistributedWant::GetFloatParam(const std::string& key, float defaultValue) const
558 {
559     auto value = parameters_.GetParam(key);
560     AAFwk::IFloat* ao = AAFwk::IFloat::Query(value);
561     if (ao != nullptr) {
562         return AAFwk::Float::Unbox(ao);
563     }
564     return defaultValue;
565 }
566 
GetFloatArrayParam(const std::string & key) const567 std::vector<float> DistributedWant::GetFloatArrayParam(const std::string& key) const
568 {
569     std::vector<float> array;
570     auto value = parameters_.GetParam(key);
571     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
572     if (ao != nullptr && AAFwk::Array::IsFloatArray(ao)) {
573         auto func = [&](AAFwk::IInterface* object) {
574             if (object != nullptr) {
575                 AAFwk::IFloat* value = AAFwk::IFloat::Query(object);
576                 if (value != nullptr) {
577                     array.push_back(AAFwk::Float::Unbox(value));
578                 }
579             }
580         };
581         AAFwk::Array::ForEach(ao, func);
582     }
583     return array;
584 }
585 
SetParam(const std::string & key,float value)586 DistributedWant& DistributedWant::SetParam(const std::string& key, float value)
587 {
588     parameters_.SetParam(key, AAFwk::Float::Box(value));
589     return *this;
590 }
591 
SetParam(const std::string & key,const std::vector<float> & value)592 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<float>& value)
593 {
594     std::size_t size = value.size();
595     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IFloat));
596     if (ao == nullptr) {
597         return *this;
598     }
599 
600     for (std::size_t i = 0; i < size; i++) {
601         ao->Set(i, AAFwk::Float::Box(value[i]));
602     }
603     parameters_.SetParam(key, ao);
604     return *this;
605 }
606 
GetLongParam(const std::string & key,long defaultValue) const607 long DistributedWant::GetLongParam(const std::string& key, long defaultValue) const
608 {
609     auto value = parameters_.GetParam(key);
610     if (AAFwk::ILong::Query(value) != nullptr) {
611         return AAFwk::Long::Unbox(AAFwk::ILong::Query(value));
612     } else if (AAFwk::IString::Query(value) != nullptr) {
613         // Marshalling
614         std::string str = AAFwk::String::Unbox(AAFwk::IString::Query(value));
615         if (std::regex_match(str, NUMBER_REGEX)) {
616             return std::atoll(str.c_str());
617         }
618     }
619 
620     return defaultValue;
621 }
622 
ArrayAddData(AAFwk::IInterface * object,std::vector<long> & array)623 void ArrayAddData(AAFwk::IInterface* object, std::vector<long>& array)
624 {
625     if (object == nullptr) {
626         return;
627     }
628 
629     AAFwk::IString* o = AAFwk::IString::Query(object);
630     if (o != nullptr) {
631         std::string str = AAFwk::String::Unbox(o);
632         if (std::regex_match(str, NUMBER_REGEX)) {
633             array.push_back(std::atoll(str.c_str()));
634         }
635     }
636 }
637 
GetLongArrayParam(const std::string & key) const638 std::vector<long> DistributedWant::GetLongArrayParam(const std::string& key) const
639 {
640     std::vector<long> array;
641     auto value = parameters_.GetParam(key);
642     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
643     if (ao != nullptr && AAFwk::Array::IsLongArray(ao)) {
644         auto func = [&](AAFwk::IInterface* object) {
645             if (object != nullptr) {
646                 AAFwk::ILong* value = AAFwk::ILong::Query(object);
647                 if (value != nullptr) {
648                     array.push_back(AAFwk::Long::Unbox(value));
649                 }
650             }
651         };
652         AAFwk::Array::ForEach(ao, func);
653     } else if (ao != nullptr && AAFwk::Array::IsStringArray(ao)) {
654         // Marshalling
655         auto func = [&](AAFwk::IInterface* object) { ArrayAddData(object, array); };
656         AAFwk::Array::ForEach(ao, func);
657     }
658     return array;
659 }
660 
SetParam(const std::string & key,long value)661 DistributedWant& DistributedWant::SetParam(const std::string& key, long value)
662 {
663     parameters_.SetParam(key, AAFwk::Long::Box(value));
664     return *this;
665 }
666 
SetParam(const std::string & key,const std::vector<long> & value)667 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<long>& value)
668 {
669     std::size_t size = value.size();
670     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_ILong));
671     if (ao == nullptr) {
672         return *this;
673     }
674     for (std::size_t i = 0; i < size; i++) {
675         ao->Set(i, AAFwk::Long::Box(value[i]));
676     }
677     parameters_.SetParam(key, ao);
678     return *this;
679 }
680 
SetParam(const std::string & key,long long value)681 DistributedWant& DistributedWant::SetParam(const std::string& key, long long value)
682 {
683     parameters_.SetParam(key, AAFwk::Long::Box(value));
684     return *this;
685 }
686 
GetShortParam(const std::string & key,short defaultValue) const687 short DistributedWant::GetShortParam(const std::string& key, short defaultValue) const
688 {
689     auto value = parameters_.GetParam(key);
690     AAFwk::IShort* ao = AAFwk::IShort::Query(value);
691     if (ao != nullptr) {
692         return AAFwk::Short::Unbox(ao);
693     }
694     return defaultValue;
695 }
696 
GetShortArrayParam(const std::string & key) const697 std::vector<short> DistributedWant::GetShortArrayParam(const std::string& key) const
698 {
699     std::vector<short> array;
700     auto value = parameters_.GetParam(key);
701     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
702     if (ao != nullptr && AAFwk::Array::IsShortArray(ao)) {
703         auto func = [&](AAFwk::IInterface* object) {
704             if (object != nullptr) {
705                 AAFwk::IShort* value = AAFwk::IShort::Query(object);
706                 if (value != nullptr) {
707                     array.push_back(AAFwk::Short::Unbox(value));
708                 }
709             }
710         };
711         AAFwk::Array::ForEach(ao, func);
712     }
713     return array;
714 }
715 
SetParam(const std::string & key,short value)716 DistributedWant& DistributedWant::SetParam(const std::string& key, short value)
717 {
718     parameters_.SetParam(key, AAFwk::Short::Box(value));
719     return *this;
720 }
721 
SetParam(const std::string & key,const std::vector<short> & value)722 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<short>& value)
723 {
724     std::size_t size = value.size();
725     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IShort));
726     if (ao == nullptr) {
727         return *this;
728     }
729     for (std::size_t i = 0; i < size; i++) {
730         ao->Set(i, AAFwk::Short::Box(value[i]));
731     }
732     parameters_.SetParam(key, ao);
733     return *this;
734 }
735 
GetStringParam(const std::string & key) const736 std::string DistributedWant::GetStringParam(const std::string& key) const
737 {
738     auto value = parameters_.GetParam(key);
739     AAFwk::IString* ao = AAFwk::IString::Query(value);
740     if (ao != nullptr) {
741         return AAFwk::String::Unbox(ao);
742     }
743     return std::string();
744 }
745 
GetStringArrayParam(const std::string & key) const746 std::vector<std::string> DistributedWant::GetStringArrayParam(const std::string& key) const
747 {
748     std::vector<std::string> array;
749     auto value = parameters_.GetParam(key);
750     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
751     if (ao != nullptr && AAFwk::Array::IsStringArray(ao)) {
752         auto func = [&](AAFwk::IInterface* object) {
753             if (object != nullptr) {
754                 AAFwk::IString* value = AAFwk::IString::Query(object);
755                 if (value != nullptr) {
756                     array.push_back(AAFwk::String::Unbox(value));
757                 }
758             }
759         };
760         AAFwk::Array::ForEach(ao, func);
761     }
762     return array;
763 }
764 
SetParam(const std::string & key,const std::string & value)765 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::string& value)
766 {
767     parameters_.SetParam(key, AAFwk::String::Box(value));
768     return *this;
769 }
770 
SetParam(const std::string & key,const std::vector<std::string> & value)771 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<std::string>& value)
772 {
773     std::size_t size = value.size();
774     sptr<AAFwk::IArray> ao(new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IString));
775     if (ao == nullptr) {
776         return *this;
777     }
778     for (std::size_t i = 0; i < size; i++) {
779         ao->Set(i, AAFwk::String::Box(value[i]));
780     }
781     parameters_.SetParam(key, ao);
782     return *this;
783 }
784 
GetOperation() const785 DistributedOperation DistributedWant::GetOperation() const
786 {
787     return operation_;
788 }
789 
SetOperation(const DistributedOperation & operation)790 void DistributedWant::SetOperation(const DistributedOperation& operation)
791 {
792     operation_ = operation;
793 }
794 
OperationEquals(const DistributedWant & want)795 bool DistributedWant::OperationEquals(const DistributedWant& want)
796 {
797     return (operation_ == want.operation_);
798 }
799 
GetUriString() const800 std::string DistributedWant::GetUriString() const
801 {
802     return operation_.GetUri().ToString();
803 }
804 
GetUri() const805 OHOS::Uri DistributedWant::GetUri() const
806 {
807     return operation_.GetUri();
808 }
809 
SetUri(const std::string & uri)810 DistributedWant& DistributedWant::SetUri(const std::string& uri)
811 {
812     operation_.SetUri(OHOS::Uri(uri));
813     return *this;
814 }
815 
SetUri(const OHOS::Uri & uri)816 DistributedWant& DistributedWant::SetUri(const OHOS::Uri& uri)
817 {
818     operation_.SetUri(uri);
819     return *this;
820 }
821 
SetUriAndType(const OHOS::Uri & uri,const std::string & type)822 DistributedWant& DistributedWant::SetUriAndType(const OHOS::Uri& uri, const std::string& type)
823 {
824     operation_.SetUri(uri);
825     return SetType(type);
826 }
827 
FormatUri(const std::string & uri)828 DistributedWant& DistributedWant::FormatUri(const std::string& uri)
829 {
830     return FormatUri(OHOS::Uri(uri));
831 }
832 
FormatUri(const OHOS::Uri & uri)833 DistributedWant& DistributedWant::FormatUri(const OHOS::Uri& uri)
834 {
835     operation_.SetUri(GetLowerCaseScheme(uri));
836     return *this;
837 }
838 
HasParameter(const std::string & key) const839 bool DistributedWant::HasParameter(const std::string& key) const
840 {
841     return parameters_.HasParam(key);
842 }
843 
ReplaceParams(DistributedWantParams & wantParams)844 DistributedWant* DistributedWant::ReplaceParams(DistributedWantParams& wantParams)
845 {
846     parameters_ = wantParams;
847     return this;
848 }
849 
ReplaceParams(DistributedWant & want)850 DistributedWant* DistributedWant::ReplaceParams(DistributedWant& want)
851 {
852     parameters_ = want.parameters_;
853     return this;
854 }
855 
RemoveParam(const std::string & key)856 void DistributedWant::RemoveParam(const std::string& key)
857 {
858     parameters_.Remove(key);
859 }
860 
ClearWant(DistributedWant * want)861 void DistributedWant::ClearWant(DistributedWant* want)
862 {
863     if (want == nullptr) {
864         return;
865     }
866     want->SetType("");
867     want->SetAction("");
868     want->SetFlags(0);
869     OHOS::AppExecFwk::ElementName elementName;
870     want->SetElement(elementName);
871     DistributedOperation operation;
872     want->SetOperation(operation);
873     DistributedWantParams parameters;
874     want->SetParams(parameters);
875 }
876 
MarshallingWriteUri(Parcel & parcel) const877 bool DistributedWant::MarshallingWriteUri(Parcel& parcel) const
878 {
879     if (GetUriString().empty()) {
880         if (!parcel.WriteInt32(VALUE_NULL)) {
881             return false;
882         }
883         return true;
884     }
885 
886     if (!parcel.WriteInt32(VALUE_OBJECT)) {
887         return false;
888     }
889 
890     if (!parcel.WriteString16(Str8ToStr16(GetUriString()))) {
891         return false;
892     }
893 
894     return true;
895 }
896 
MarshallingWriteEntities(Parcel & parcel) const897 bool DistributedWant::MarshallingWriteEntities(Parcel& parcel) const
898 {
899     std::vector<std::u16string> entityU16;
900     std::vector<std::string> entities = GetEntities();
901     for (std::vector<std::string>::size_type i = 0; i < entities.size(); i++) {
902         entityU16.push_back(Str8ToStr16(entities[i]));
903     }
904     if (entityU16.size() == 0) {
905         if (!parcel.WriteInt32(VALUE_NULL)) {
906             return false;
907         }
908     } else {
909         if (!parcel.WriteInt32(VALUE_OBJECT)) {
910             return false;
911         }
912         if (!parcel.WriteString16Vector(entityU16)) {
913             return false;
914         }
915     }
916     return true;
917 }
918 
MarshallingWriteElement(Parcel & parcel) const919 bool DistributedWant::MarshallingWriteElement(Parcel& parcel) const
920 {
921     ElementName empty;
922     ElementName element = GetElement();
923     if (element == empty) {
924         if (!parcel.WriteInt32(VALUE_NULL)) {
925             return false;
926         }
927     } else {
928         if (!parcel.WriteInt32(VALUE_OBJECT)) {
929             return false;
930         }
931         if (!parcel.WriteParcelable(&element)) {
932             return false;
933         }
934     }
935     return true;
936 }
937 
MarshallingWriteParameters(Parcel & parcel) const938 bool DistributedWant::MarshallingWriteParameters(Parcel& parcel) const
939 {
940     if (parameters_.Size() == 0) {
941         if (!parcel.WriteInt32(VALUE_NULL)) {
942             return false;
943         }
944         return true;
945     }
946 
947     if (!parcel.WriteInt32(VALUE_OBJECT)) {
948         return false;
949     }
950 
951     if (!parcel.WriteParcelable(&parameters_)) {
952         return false;
953     }
954     return true;
955 }
956 
Marshalling(Parcel & parcel) const957 bool DistributedWant::Marshalling(Parcel& parcel) const
958 {
959     // write action
960     if (!parcel.WriteString16(Str8ToStr16(GetAction()))) {
961         return false;
962     }
963     // write uri
964     if (!MarshallingWriteUri(parcel)) {
965         return false;
966     }
967     // write entities
968     if (!MarshallingWriteEntities(parcel)) {
969         return false;
970     }
971     // write flags
972     if (!parcel.WriteUint32(GetFlags())) {
973         return false;
974     }
975     // write element
976     if (!MarshallingWriteElement(parcel)) {
977         return false;
978     }
979     // write parameters
980     if (!MarshallingWriteParameters(parcel)) {
981         return false;
982     }
983     // write package
984     if (!parcel.WriteString16(Str8ToStr16(GetBundle()))) {
985         return false;
986     }
987     return true;
988 }
989 
Unmarshalling(Parcel & parcel)990 DistributedWant* DistributedWant::Unmarshalling(Parcel& parcel)
991 {
992     DistributedWant* want = new (std::nothrow) DistributedWant();
993     if (want != nullptr && !want->ReadFromParcel(parcel)) {
994         delete want;
995         want = nullptr;
996     }
997     return want;
998 }
999 
ReadUriFromParcel(Parcel & parcel)1000 bool DistributedWant::ReadUriFromParcel(Parcel& parcel)
1001 {
1002     int value = VALUE_NULL;
1003     if (!parcel.ReadInt32(value)) {
1004         return false;
1005     }
1006     if (value == VALUE_OBJECT) {
1007         SetUri(Str16ToStr8(parcel.ReadString16()));
1008     }
1009     return true;
1010 }
1011 
ReadEntitiesFromParcel(Parcel & parcel)1012 bool DistributedWant::ReadEntitiesFromParcel(Parcel& parcel)
1013 {
1014     std::vector<std::string> entities;
1015     std::vector<std::u16string> entityU16;
1016     int value = VALUE_NULL;
1017     if (!parcel.ReadInt32(value)) {
1018         return false;
1019     }
1020     if (value == VALUE_OBJECT) {
1021         if (!parcel.ReadString16Vector(&entityU16)) {
1022             return false;
1023         }
1024     }
1025     for (std::vector<std::u16string>::size_type i = 0; i < entityU16.size(); i++) {
1026         entities.push_back(Str16ToStr8(entityU16[i]));
1027     }
1028     operation_.SetEntities(entities);
1029     return true;
1030 }
1031 
ReadElementFromParcel(Parcel & parcel)1032 bool DistributedWant::ReadElementFromParcel(Parcel& parcel)
1033 {
1034     int value = VALUE_NULL;
1035     if (!parcel.ReadInt32(value)) {
1036         return false;
1037     }
1038     if (value == VALUE_OBJECT) {
1039         auto element = parcel.ReadParcelable<ElementName>();
1040         if (element != nullptr) {
1041             SetElement(*element);
1042             delete element;
1043         } else {
1044             return false;
1045         }
1046     }
1047     return true;
1048 }
1049 
ReadParametersFromParcel(Parcel & parcel)1050 bool DistributedWant::ReadParametersFromParcel(Parcel& parcel)
1051 {
1052     int empty = VALUE_NULL;
1053     if (!parcel.ReadInt32(empty)) {
1054         return false;
1055     }
1056     if (empty == VALUE_OBJECT) {
1057         auto params = parcel.ReadParcelable<DistributedWantParams>();
1058         if (params != nullptr) {
1059             parameters_ = *params;
1060             delete params;
1061             params = nullptr;
1062         } else {
1063             return false;
1064         }
1065     }
1066     return true;
1067 }
1068 
ReadFromParcel(Parcel & parcel)1069 bool DistributedWant::ReadFromParcel(Parcel& parcel)
1070 {
1071     // read action
1072     operation_.SetAction(Str16ToStr8(parcel.ReadString16()));
1073     // read uri
1074     if (!ReadUriFromParcel(parcel)) {
1075         return false;
1076     }
1077     // read entities
1078     if (!ReadEntitiesFromParcel(parcel)) {
1079         return false;
1080     }
1081     // read flags
1082     unsigned int flags;
1083     if (!parcel.ReadUint32(flags)) {
1084         return false;
1085     }
1086     operation_.SetFlags(flags);
1087     // read element
1088     if (!ReadElementFromParcel(parcel)) {
1089         return false;
1090     }
1091     // read parameters
1092     if (!ReadParametersFromParcel(parcel)) {
1093         return false;
1094     }
1095     // read package
1096     operation_.SetBundleName(Str16ToStr8(parcel.ReadString16()));
1097     return true;
1098 }
1099 
ToJson() const1100 nlohmann::json DistributedWant::ToJson() const
1101 {
1102     DistributedWantParamWrapper wrapper(parameters_);
1103     std::string parametersString = wrapper.ToString();
1104 
1105     nlohmann::json dEntitiesJson;
1106     std::vector<std::string> entities = GetEntities();
1107     for (auto entity : entities) {
1108         dEntitiesJson.emplace_back(entity);
1109     }
1110 
1111     nlohmann::json wantJson = nlohmann::json {
1112         {"deviceId", operation_.GetDeviceId()},
1113         {"bundleName", operation_.GetBundleName()},
1114         {"abilityName", operation_.GetAbilityName()},
1115         {"uri", GetUriString()},
1116         {"type", GetType()},
1117         {"flags", GetFlags()},
1118         {"action", GetAction()},
1119         {"parameters", parametersString},
1120         {"entities", dEntitiesJson},
1121     };
1122     return wantJson;
1123 }
1124 
CanReadFromJson(nlohmann::json & wantJson)1125 bool DistributedWant::CanReadFromJson(nlohmann::json& wantJson)
1126 {
1127     const auto& jsonObjectEnd = wantJson.end();
1128     if ((wantJson.find("deviceId") == jsonObjectEnd)
1129         || (wantJson.find("bundleName") == jsonObjectEnd)
1130         || (wantJson.find("abilityName") == jsonObjectEnd)
1131         || (wantJson.find("uri") == jsonObjectEnd)
1132         || (wantJson.find("type") == jsonObjectEnd)
1133         || (wantJson.find("flags") == jsonObjectEnd)
1134         || (wantJson.find("action") == jsonObjectEnd)
1135         || (wantJson.find("parameters") == jsonObjectEnd)
1136         || (wantJson.find("entities") == jsonObjectEnd)) {
1137         return false;
1138     }
1139     if (!wantJson["deviceId"].is_string()) {
1140         HILOGE("device id is not string");
1141         return false;
1142     }
1143     if (!wantJson["bundleName"].is_string()) {
1144         HILOGE("bundle name is not string");
1145         return false;
1146     }
1147     if (!wantJson["abilityName"].is_string()) {
1148         HILOGE("ability name is not string");
1149         return false;
1150     }
1151     if (!wantJson["uri"].is_string()) {
1152         HILOGE("uri is not string");
1153         return false;
1154     }
1155     if (!wantJson["type"].is_string()) {
1156         HILOGE("type is not string");
1157         return false;
1158     }
1159     if (!wantJson["flags"].is_number_unsigned()) {
1160         HILOGE("flags is not a number");
1161         return false;
1162     }
1163     if (!wantJson["action"].is_string()) {
1164         HILOGE("action is not string");
1165         return false;
1166     }
1167     if (!wantJson["parameters"].is_string()) {
1168         HILOGE("parameters is not string");
1169         return false;
1170     }
1171     return true;
1172 }
1173 
ReadFromJson(nlohmann::json & wantJson)1174 bool DistributedWant::ReadFromJson(nlohmann::json& wantJson)
1175 {
1176     if (!CanReadFromJson(wantJson)) {
1177         HILOGE("can not read from json");
1178         return false;
1179     }
1180     if (!wantJson.contains("deviceId") || !wantJson.contains("bundleName") || !wantJson.contains("abilityName") ||
1181         !wantJson.contains("uri") || !wantJson.contains("type") || !wantJson.contains("flags") ||
1182         !wantJson.contains("action") || !wantJson.contains("parameters") || !wantJson.contains("entities")) {
1183         HILOGE("data is empty");
1184         return false;
1185     }
1186 
1187     std::string deviceId = wantJson.at("deviceId").get<std::string>();
1188     std::string bundleName = wantJson.at("bundleName").get<std::string>();
1189     std::string abilityName = wantJson.at("abilityName").get<std::string>();
1190     SetElementName(deviceId, bundleName, abilityName);
1191 
1192     std::string uri = wantJson.at("uri").get<std::string>();
1193     SetUri(uri);
1194 
1195     std::string type = wantJson.at("type").get<std::string>();
1196     SetType(type);
1197 
1198     if (!wantJson.at("flags").is_number()) {
1199         return false;
1200     }
1201     unsigned int flags = wantJson.at("flags").get<unsigned int>();
1202     SetFlags(flags);
1203 
1204     std::string action = wantJson.at("action").get<std::string>();
1205     SetAction(action);
1206 
1207     if (!wantJson.at("parameters").is_string()) {
1208         return false;
1209     }
1210     std::string parametersString = wantJson.at("parameters").get<std::string>();
1211     DistributedWantParams parameters = DistributedWantParamWrapper::ParseWantParams(parametersString);
1212     SetParams(parameters);
1213     if (!wantJson.at("entities").is_null()) {
1214         std::vector<std::string> entities;
1215         wantJson.at("entities").get_to<std::vector<std::string>>(entities);
1216         for (size_t i = 0; i < entities.size(); i++) {
1217             AddEntity(entities[i]);
1218         }
1219     }
1220     return true;
1221 }
1222 
ToString() const1223 std::string DistributedWant::ToString() const
1224 {
1225     return ToJson().dump();
1226 }
1227 
FromString(std::string & string)1228 DistributedWant* DistributedWant::FromString(std::string& string)
1229 {
1230     if (string.empty()) {
1231         return nullptr;
1232     }
1233 
1234     nlohmann::json wantJson = nlohmann::json::parse(string, nullptr, false);
1235     if (wantJson.is_discarded()) {
1236         return nullptr;
1237     }
1238 
1239     DistributedWant* want = new (std::nothrow) DistributedWant();
1240     if (want != nullptr && !want->ReadFromJson(wantJson)) {
1241         delete want;
1242         want = nullptr;
1243     }
1244     return want;
1245 }
1246 
SetDeviceId(const std::string & deviceId)1247 DistributedWant& DistributedWant::SetDeviceId(const std::string& deviceId)
1248 {
1249     operation_.SetDeviceId(deviceId);
1250     return *this;
1251 }
1252 } // namespace DistributedSchedule
1253 } // namespace OHOS
1254