• 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 "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_object.h"
26 #include "bool_wrapper.h"
27 #include "byte_wrapper.h"
28 #include "distributed_operation_builder.h"
29 #include "distributed_want_params_wrapper.h"
30 #include "double_wrapper.h"
31 #include "dtbschedmgr_log.h"
32 #include "float_wrapper.h"
33 #include "int_wrapper.h"
34 #include "long_wrapper.h"
35 #include "parcel_macro_base.h"
36 #include "remote_object_wrapper.h"
37 #include "short_wrapper.h"
38 #include "string_ex.h"
39 #include "string_wrapper.h"
40 #include "zchar_wrapper.h"
41 
42 using namespace OHOS::AppExecFwk;
43 using OHOS::AppExecFwk::ElementName;
44 namespace OHOS {
45 namespace DistributedSchedule {
46 namespace {
47 const std::regex NUMBER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$");
48 const std::string TAG = "DistributedWant";
49 const char* REMOTE_OBJECT = "RemoteObject";
50 const char* TYPE_PROPERTY = "type";
51 const char* VALUE_PROPERTY = "value";
52 };  // namespace
53 const std::string DistributedWant::ACTION_PLAY("action.system.play");
54 const std::string DistributedWant::ACTION_HOME("action.system.home");
55 
56 const std::string DistributedWant::ENTITY_HOME("entity.system.home");
57 const std::string DistributedWant::ENTITY_VIDEO("entity.system.video");
58 const std::string DistributedWant::FLAG_HOME_INTENT_FROM_SYSTEM("flag.home.intent.from.system");
59 const std::string DistributedWant::ENTITY_MUSIC("entity.app.music");
60 const std::string DistributedWant::ENTITY_EMAIL("entity.app.email");
61 const std::string DistributedWant::ENTITY_CONTACTS("entity.app.contacts");
62 const std::string DistributedWant::ENTITY_MAPS("entity.app.maps");
63 const std::string DistributedWant::ENTITY_BROWSER("entity.app.browser");
64 const std::string DistributedWant::ENTITY_CALENDAR("entity.app.calendar");
65 const std::string DistributedWant::ENTITY_MESSAGING("entity.app.messaging");
66 const std::string DistributedWant::ENTITY_FILES("entity.app.files");
67 const std::string DistributedWant::ENTITY_GALLERY("entity.app.gallery");
68 
69 const std::string DistributedWant::OCT_EQUALSTO("075");   // '='
70 const std::string DistributedWant::OCT_SEMICOLON("073");  // ';'
71 const std::string DistributedWant::MIME_TYPE("mime-type");
72 const std::string DistributedWant::WANT_HEADER("#Intent;");
73 
74 const std::string DistributedWant::PARAM_RESV_WINDOW_MODE("ohos.aafwk.param.windowMode");
75 const std::string DistributedWant::PARAM_RESV_DISPLAY_ID("ohos.aafwk.param.displayId");
76 const std::string DistributedWant::PARAM_RESV_CALLER_TOKEN("ohos.aafwk.param.callerToken");
77 const std::string DistributedWant::PARAM_RESV_CALLER_UID("ohos.aafwk.param.callerUid");
78 const std::string DistributedWant::PARAM_RESV_CALLER_PID("ohos.aafwk.param.callerPid");
79 
DistributedWant()80 DistributedWant::DistributedWant()
81 {}
82 
~DistributedWant()83 DistributedWant::~DistributedWant()
84 {}
85 
DistributedWant(const DistributedWant & other)86 DistributedWant::DistributedWant(const DistributedWant& other)
87 {
88     operation_ = other.operation_;
89     parameters_ = other.parameters_;
90 }
91 
operator =(const DistributedWant & other)92 DistributedWant& DistributedWant::operator=(const DistributedWant& other)
93 {
94     operation_ = other.operation_;
95     parameters_ = other.parameters_;
96     return *this;
97 }
98 
DistributedWant(const AAFwk::Want & want)99 DistributedWant::DistributedWant(const AAFwk::Want& want)
100 {
101     DistributedOperationBuilder builder;
102     builder.WithAbilityName(want.GetElement().GetAbilityName());
103     builder.WithBundleName(want.GetElement().GetBundleName());
104     builder.WithDeviceId(want.GetElement().GetDeviceID());
105     builder.WithAction(want.GetAction());
106     builder.WithEntities(want.GetEntities());
107     builder.WithFlags(want.GetFlags());
108     builder.WithUri(want.GetUri());
109     std::shared_ptr<DistributedOperation> op = builder.build();
110     operation_ = *op;
111     std::map<std::string, sptr<AAFwk::IInterface>> data = want.GetParams().GetParams();
112     for (auto it = data.begin(); it != data.end(); it++) {
113         auto tp = AAFwk::WantParams::GetDataType(it->second);
114         if ((tp == DistributedWantParams::VALUE_TYPE_BOOLEAN) ||
115             (tp == DistributedWantParams::VALUE_TYPE_BYTE) ||
116             (tp == DistributedWantParams::VALUE_TYPE_CHAR) ||
117             (tp == DistributedWantParams::VALUE_TYPE_SHORT) ||
118             (tp == DistributedWantParams::VALUE_TYPE_INT) ||
119             (tp == DistributedWantParams::VALUE_TYPE_LONG) ||
120             (tp == DistributedWantParams::VALUE_TYPE_FLOAT) ||
121             (tp == DistributedWantParams::VALUE_TYPE_DOUBLE) ||
122             (tp == DistributedWantParams::VALUE_TYPE_STRING) ||
123             (tp == DistributedWantParams::VALUE_TYPE_ARRAY) ||
124             (tp == DistributedWantParams::VALUE_TYPE_REMOTE_OBJECT) ||
125             (tp == DistributedWantParams::VALUE_TYPE_WANTPARAMS)) {
126             parameters_.SetParam(it->first, it->second);
127         }
128     }
129 }
130 
ToWant()131 std::shared_ptr<AAFwk::Want> DistributedWant::ToWant()
132 {
133     auto want = std::make_shared<AAFwk::Want>();
134     want->SetFlags(GetFlags());
135     want->SetElement(GetElement());
136     want->SetUri(GetUri());
137     want->SetAction(GetAction());
138     want->SetBundle(GetBundle());
139     want->SetType(GetType());
140     std::vector<std::string> ents = GetEntities();
141     for (auto it = ents.begin(); it != ents.end(); it++) {
142         want->AddEntity(*it);
143     }
144     want->SetParams(parameters_.ToWantParams());
145     return want;
146 }
147 
GetFlags() const148 unsigned int DistributedWant::GetFlags() const
149 {
150     return operation_.GetFlags();
151 }
152 
SetFlags(unsigned int flags)153 DistributedWant& DistributedWant::SetFlags(unsigned int flags)
154 {
155     operation_.SetFlags(flags);
156     return *this;
157 }
158 
AddFlags(unsigned int flags)159 DistributedWant& DistributedWant::AddFlags(unsigned int flags)
160 {
161     operation_.AddFlags(flags);
162     return *this;
163 }
164 
RemoveFlags(unsigned int flags)165 void DistributedWant::RemoveFlags(unsigned int flags)
166 {
167     operation_.RemoveFlags(flags);
168 }
169 
GetElement() const170 OHOS::AppExecFwk::ElementName DistributedWant::GetElement() const
171 {
172     return ElementName(operation_.GetDeviceId(), operation_.GetBundleName(), operation_.GetAbilityName());
173 }
174 
SetElementName(const std::string & bundleName,const std::string & abilityName)175 DistributedWant& DistributedWant::SetElementName(const std::string& bundleName, const std::string& abilityName)
176 {
177     operation_.SetBundleName(bundleName);
178     operation_.SetAbilityName(abilityName);
179     return *this;
180 }
181 
SetElementName(const std::string & deviceId,const std::string & bundleName,const std::string & abilityName)182 DistributedWant& DistributedWant::SetElementName(const std::string& deviceId, const std::string& bundleName,
183                                                  const std::string& abilityName)
184 {
185     operation_.SetDeviceId(deviceId);
186     operation_.SetBundleName(bundleName);
187     operation_.SetAbilityName(abilityName);
188     return *this;
189 }
190 
SetElement(const OHOS::AppExecFwk::ElementName & element)191 DistributedWant& DistributedWant::SetElement(const OHOS::AppExecFwk::ElementName& element)
192 {
193     operation_.SetDeviceId(element.GetDeviceID());
194     operation_.SetBundleName(element.GetBundleName());
195     operation_.SetAbilityName(element.GetAbilityName());
196     return *this;
197 }
198 
GetEntities() const199 const std::vector<std::string>& DistributedWant::GetEntities() const
200 {
201     return operation_.GetEntities();
202 }
203 
AddEntity(const std::string & entity)204 DistributedWant& DistributedWant::AddEntity(const std::string& entity)
205 {
206     operation_.AddEntity(entity);
207     return *this;
208 }
209 
RemoveEntity(const std::string & entity)210 void DistributedWant::RemoveEntity(const std::string& entity)
211 {
212     operation_.RemoveEntity(entity);
213 }
214 
HasEntity(const std::string & entity) const215 bool DistributedWant::HasEntity(const std::string& entity) const
216 {
217     return operation_.HasEntity(entity);
218 }
219 
CountEntities()220 int DistributedWant::CountEntities()
221 {
222     return operation_.CountEntities();
223 }
224 
GetBundle() const225 std::string DistributedWant::GetBundle() const
226 {
227     return operation_.GetBundleName();
228 }
229 
SetBundle(const std::string & bundleName)230 DistributedWant& DistributedWant::SetBundle(const std::string& bundleName)
231 {
232     operation_.SetBundleName(bundleName);
233     return *this;
234 }
235 
GetType() const236 std::string DistributedWant::GetType() const
237 {
238     auto value = parameters_.GetParam(MIME_TYPE);
239     AAFwk::IString* ao = AAFwk::IString::Query(value);
240     if (ao != nullptr) {
241         return AAFwk::String::Unbox(ao);
242     }
243     return std::string();
244 }
245 
SetType(const std::string & type)246 DistributedWant& DistributedWant::SetType(const std::string& type)
247 {
248     sptr<AAFwk::IString> valueObj = AAFwk::String::Parse(type);
249     parameters_.SetParam(MIME_TYPE, valueObj);
250     return *this;
251 }
252 
FormatType(const std::string & type)253 DistributedWant& DistributedWant::FormatType(const std::string& type)
254 {
255     std::string typetemp = FormatMimeType(type);
256     SetType(typetemp);
257     return *this;
258 }
259 
GetLowerCaseScheme(const Uri & uri)260 Uri DistributedWant::GetLowerCaseScheme(const Uri& uri)
261 {
262     std::string strUri = const_cast<Uri&>(uri).ToString();
263     std::string schemeStr = const_cast<Uri&>(uri).GetScheme();
264     if (strUri.empty() || schemeStr.empty()) {
265         return uri;
266     }
267 
268     std::string lowSchemeStr = schemeStr;
269     std::transform(lowSchemeStr.begin(), lowSchemeStr.end(), lowSchemeStr.begin(), [](unsigned char c) {
270         return std::tolower(c);
271     });
272 
273     if (schemeStr == lowSchemeStr) {
274         return uri;
275     }
276 
277     std::size_t pos = strUri.find_first_of(schemeStr, 0);
278     if (pos != std::string::npos) {
279         strUri.replace(pos, schemeStr.length(), lowSchemeStr);
280     }
281 
282     return Uri(strUri);
283 }
284 
FormatUriAndType(const Uri & uri,const std::string & type)285 DistributedWant& DistributedWant::FormatUriAndType(const Uri& uri, const std::string& type)
286 {
287     return SetUriAndType(GetLowerCaseScheme(uri), FormatMimeType(type));
288 }
289 
FormatMimeType(const std::string & mimeType)290 std::string DistributedWant::FormatMimeType(const std::string& mimeType)
291 {
292     std::string strMimeType = mimeType;
293     strMimeType.erase(std::remove(strMimeType.begin(), strMimeType.end(), ' '), strMimeType.end());
294     std::transform(
295         strMimeType.begin(), strMimeType.end(), strMimeType.begin(), [](unsigned char c) { return std::tolower(c); });
296 
297     std::size_t pos = 0;
298     std::size_t begin = 0;
299     pos = strMimeType.find_first_of(";", begin);
300     if (pos != std::string::npos) {
301         strMimeType = strMimeType.substr(begin, pos - begin);
302     }
303     return strMimeType;
304 }
305 
GetAction() const306 std::string DistributedWant::GetAction() const
307 {
308     return operation_.GetAction();
309 }
310 
SetAction(const std::string & action)311 DistributedWant& DistributedWant::SetAction(const std::string& action)
312 {
313     operation_.SetAction(action);
314     return *this;
315 }
316 
GetScheme() const317 const std::string DistributedWant::GetScheme() const
318 {
319     return operation_.GetUri().GetScheme();
320 }
321 
MakeMainAbility(const OHOS::AppExecFwk::ElementName & elementName)322 DistributedWant* DistributedWant::MakeMainAbility(const OHOS::AppExecFwk::ElementName& elementName)
323 {
324     DistributedWant* want = new (std::nothrow) DistributedWant();
325     if (want != nullptr) {
326         want->SetAction(ACTION_HOME);
327         want->AddEntity(ENTITY_HOME);
328         want->SetElement(elementName);
329     } else {
330         return nullptr;
331     }
332     return want;
333 }
334 
GetParams() const335 const DistributedWantParams& DistributedWant::GetParams() const
336 {
337     return parameters_;
338 }
339 
SetParams(const DistributedWantParams & wantParams)340 DistributedWant& DistributedWant::SetParams(const DistributedWantParams& wantParams)
341 {
342     parameters_ = wantParams;
343     return *this;
344 }
345 
GetBoolParam(const std::string & key,bool defaultValue) const346 bool DistributedWant::GetBoolParam(const std::string& key, bool defaultValue) const
347 {
348     auto value = parameters_.GetParam(key);
349     AAFwk::IBoolean* bo = AAFwk::IBoolean::Query(value);
350     if (bo != nullptr) {
351         return AAFwk::Boolean::Unbox(bo);
352     }
353     return defaultValue;
354 }
355 
GetBoolArrayParam(const std::string & key) const356 std::vector<bool> DistributedWant::GetBoolArrayParam(const std::string& key) const
357 {
358     std::vector<bool> array;
359     auto value = parameters_.GetParam(key);
360     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
361     if (ao != nullptr && AAFwk::Array::IsBooleanArray(ao)) {
362         auto func = [&](AAFwk::IInterface* object) {
363             if (object != nullptr) {
364                 AAFwk::IBoolean* value = AAFwk::IBoolean::Query(object);
365                 if (value != nullptr) {
366                     array.push_back(AAFwk::Boolean::Unbox(value));
367                 }
368             }
369         };
370         AAFwk::Array::ForEach(ao, func);
371     }
372     return array;
373 }
374 
SetParam(const std::string & key,const sptr<IRemoteObject> & remoteObject)375 DistributedWant& DistributedWant::SetParam(const std::string& key, const sptr<IRemoteObject>& remoteObject)
376 {
377     DistributedWantParams wp;
378     wp.SetParam(TYPE_PROPERTY, AAFwk::String::Box(AAFwk::REMOTE_OBJECT));
379     wp.SetParam(AAFwk::VALUE_PROPERTY, AAFwk::RemoteObjectWrap::Box(remoteObject));
380     parameters_.SetParam(key, DistributedWantParamWrapper::Box(wp));
381     return *this;
382 }
383 
GetRemoteObject(const std::string & key) const384 sptr<IRemoteObject> DistributedWant::GetRemoteObject(const std::string& key) const
385 {
386     auto value = parameters_.GetParam(key);
387     IDistributedWantParams* iwp = IDistributedWantParams::Query(value);
388     if (iwp == nullptr) {
389         return nullptr;
390     }
391     auto wp = DistributedWantParamWrapper::Unbox(iwp);
392 
393     auto type = wp.GetParam(TYPE_PROPERTY);
394     AAFwk::IString* iString = AAFwk::IString::Query(type);
395     if (iString == nullptr) {
396         return nullptr;
397     }
398     if (REMOTE_OBJECT != AAFwk::String::Unbox(iString)) {
399         return nullptr;
400     }
401 
402     auto remoteObjVal = wp.GetParam(VALUE_PROPERTY);
403     AAFwk::IRemoteObjectWrap* iRemoteObj = AAFwk::IRemoteObjectWrap::Query(remoteObjVal);
404     if (iRemoteObj == nullptr) {
405         return nullptr;
406     }
407     return AAFwk::RemoteObjectWrap::UnBox(iRemoteObj);
408 }
409 
SetParam(const std::string & key,bool value)410 DistributedWant& DistributedWant::SetParam(const std::string& key, bool value)
411 {
412     parameters_.SetParam(key, AAFwk::Boolean::Box(value));
413     return *this;
414 }
415 
SetParam(const std::string & key,const std::vector<bool> & value)416 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<bool>& value)
417 {
418     std::size_t size = value.size();
419     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IBoolean);
420     if (ao != nullptr) {
421         for (std::size_t i = 0; i < size; i++) {
422             ao->Set(i, AAFwk::Boolean::Box(value[i]));
423         }
424         parameters_.SetParam(key, ao);
425     }
426     return *this;
427 }
428 
GetByteParam(const std::string & key,const AAFwk::byte defaultValue) const429 AAFwk::byte DistributedWant::GetByteParam(const std::string& key, const AAFwk::byte defaultValue) const
430 {
431     auto value = parameters_.GetParam(key);
432     AAFwk::IByte* bo = AAFwk::IByte::Query(value);
433     if (bo != nullptr) {
434         return AAFwk::Byte::Unbox(bo);
435     }
436     return defaultValue;
437 }
438 
GetByteArrayParam(const std::string & key) const439 std::vector<AAFwk::byte> DistributedWant::GetByteArrayParam(const std::string& key) const
440 {
441     std::vector<AAFwk::byte> array;
442     auto value = parameters_.GetParam(key);
443     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
444     if (ao != nullptr && AAFwk::Array::IsByteArray(ao)) {
445         auto func = [&](AAFwk::IInterface* object) {
446             if (object != nullptr) {
447                 AAFwk::IByte* value = AAFwk::IByte::Query(object);
448                 if (value != nullptr) {
449                     array.push_back(AAFwk::Byte::Unbox(value));
450                 }
451             }
452         };
453         AAFwk::Array::ForEach(ao, func);
454     }
455     return array;
456 }
457 
SetParam(const std::string & key,AAFwk::byte value)458 DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::byte value)
459 {
460     parameters_.SetParam(key, AAFwk::Byte::Box(value));
461     return *this;
462 }
463 
SetParam(const std::string & key,const std::vector<AAFwk::byte> & value)464 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<AAFwk::byte>& value)
465 {
466     std::size_t size = value.size();
467     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IByte);
468     if (ao == nullptr) {
469         return *this;
470     }
471     for (std::size_t i = 0; i < size; i++) {
472         ao->Set(i, AAFwk::Byte::Box(value[i]));
473     }
474     parameters_.SetParam(key, ao);
475     return *this;
476 }
477 
GetCharParam(const std::string & key,AAFwk::zchar defaultValue) const478 AAFwk::zchar DistributedWant::GetCharParam(const std::string& key, AAFwk::zchar defaultValue) const
479 {
480     auto value = parameters_.GetParam(key);
481     AAFwk::IChar* ao = AAFwk::IChar::Query(value);
482     if (ao != nullptr) {
483         return AAFwk::Char::Unbox(ao);
484     }
485     return defaultValue;
486 }
487 
GetCharArrayParam(const std::string & key) const488 std::vector<AAFwk::zchar> DistributedWant::GetCharArrayParam(const std::string& key) const
489 {
490     std::vector<AAFwk::zchar> array;
491     auto value = parameters_.GetParam(key);
492     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
493     if (ao != nullptr && AAFwk::Array::IsCharArray(ao)) {
494         auto func = [&](AAFwk::IInterface* object) {
495             if (object != nullptr) {
496                 AAFwk::IChar* value = AAFwk::IChar::Query(object);
497                 if (value != nullptr) {
498                     array.push_back(AAFwk::Char::Unbox(value));
499                 }
500             }
501         };
502         AAFwk::Array::ForEach(ao, func);
503     }
504     return array;
505 }
506 
SetParam(const std::string & key,AAFwk::zchar value)507 DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::zchar value)
508 {
509     parameters_.SetParam(key, AAFwk::Char::Box(value));
510     return *this;
511 }
512 
SetParam(const std::string & key,const std::vector<AAFwk::zchar> & value)513 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<AAFwk::zchar>& value)
514 {
515     std::size_t size = value.size();
516     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IChar);
517     if (ao == nullptr) {
518         return *this;
519     }
520     for (std::size_t i = 0; i < size; i++) {
521         ao->Set(i, AAFwk::Char::Box(value[i]));
522     }
523     parameters_.SetParam(key, ao);
524     return *this;
525 }
526 
GetIntParam(const std::string & key,const int defaultValue) const527 int DistributedWant::GetIntParam(const std::string& key, const int defaultValue) const
528 {
529     auto value = parameters_.GetParam(key);
530     AAFwk::IInteger* ao = AAFwk::IInteger::Query(value);
531     if (ao != nullptr) {
532         return AAFwk::Integer::Unbox(ao);
533     }
534     return defaultValue;
535 }
536 
GetIntArrayParam(const std::string & key) const537 std::vector<int> DistributedWant::GetIntArrayParam(const std::string& key) const
538 {
539     std::vector<int> array;
540     auto value = parameters_.GetParam(key);
541     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
542     if (ao != nullptr && AAFwk::Array::IsIntegerArray(ao)) {
543         auto func = [&](AAFwk::IInterface* object) {
544             if (object != nullptr) {
545                 AAFwk::IInteger* value = AAFwk::IInteger::Query(object);
546                 if (value != nullptr) {
547                     array.push_back(AAFwk::Integer::Unbox(value));
548                 }
549             }
550         };
551         AAFwk::Array::ForEach(ao, func);
552     }
553     return array;
554 }
555 
SetParam(const std::string & key,int value)556 DistributedWant& DistributedWant::SetParam(const std::string& key, int value)
557 {
558     parameters_.SetParam(key, AAFwk::Integer::Box(value));
559     return *this;
560 }
561 
SetParam(const std::string & key,const std::vector<int> & value)562 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<int>& value)
563 {
564     std::size_t size = value.size();
565     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IInteger);
566     if (ao == nullptr) {
567         return *this;
568     }
569     for (std::size_t i = 0; i < size; i++) {
570         ao->Set(i, AAFwk::Integer::Box(value[i]));
571     }
572     parameters_.SetParam(key, ao);
573     return *this;
574 }
575 
GetDoubleParam(const std::string & key,double defaultValue) const576 double DistributedWant::GetDoubleParam(const std::string& key, double defaultValue) const
577 {
578     auto value = parameters_.GetParam(key);
579     AAFwk::IDouble* ao = AAFwk::IDouble::Query(value);
580     if (ao != nullptr) {
581         return AAFwk::Double::Unbox(ao);
582     }
583     return defaultValue;
584 }
585 
GetDoubleArrayParam(const std::string & key) const586 std::vector<double> DistributedWant::GetDoubleArrayParam(const std::string& key) const
587 {
588     std::vector<double> array;
589     auto value = parameters_.GetParam(key);
590     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
591     if (ao != nullptr && AAFwk::Array::IsDoubleArray(ao)) {
592         auto func = [&](AAFwk::IInterface* object) {
593             if (object != nullptr) {
594                 AAFwk::IDouble* value = AAFwk::IDouble::Query(object);
595                 if (value != nullptr) {
596                     array.push_back(AAFwk::Double::Unbox(value));
597                 }
598             }
599         };
600         AAFwk::Array::ForEach(ao, func);
601     }
602     return array;
603 }
604 
SetParam(const std::string & key,double value)605 DistributedWant& DistributedWant::SetParam(const std::string& key, double value)
606 {
607     parameters_.SetParam(key, AAFwk::Double::Box(value));
608     return *this;
609 }
610 
SetParam(const std::string & key,const std::vector<double> & value)611 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<double>& value)
612 {
613     std::size_t size = value.size();
614     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IDouble);
615     if (ao == nullptr) {
616         return *this;
617     }
618     for (std::size_t i = 0; i < size; i++) {
619         ao->Set(i, AAFwk::Double::Box(value[i]));
620     }
621     parameters_.SetParam(key, ao);
622     return *this;
623 }
624 
GetFloatParam(const std::string & key,float defaultValue) const625 float DistributedWant::GetFloatParam(const std::string& key, float defaultValue) const
626 {
627     auto value = parameters_.GetParam(key);
628     AAFwk::IFloat* ao = AAFwk::IFloat::Query(value);
629     if (ao != nullptr) {
630         return AAFwk::Float::Unbox(ao);
631     }
632     return defaultValue;
633 }
634 
GetFloatArrayParam(const std::string & key) const635 std::vector<float> DistributedWant::GetFloatArrayParam(const std::string& key) const
636 {
637     std::vector<float> array;
638     auto value = parameters_.GetParam(key);
639     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
640     if (ao != nullptr && AAFwk::Array::IsFloatArray(ao)) {
641         auto func = [&](AAFwk::IInterface* object) {
642             if (object != nullptr) {
643                 AAFwk::IFloat* value = AAFwk::IFloat::Query(object);
644                 if (value != nullptr) {
645                     array.push_back(AAFwk::Float::Unbox(value));
646                 }
647             }
648         };
649         AAFwk::Array::ForEach(ao, func);
650     }
651     return array;
652 }
653 
SetParam(const std::string & key,float value)654 DistributedWant& DistributedWant::SetParam(const std::string& key, float value)
655 {
656     parameters_.SetParam(key, AAFwk::Float::Box(value));
657     return *this;
658 }
659 
SetParam(const std::string & key,const std::vector<float> & value)660 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<float>& value)
661 {
662     std::size_t size = value.size();
663     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IFloat);
664     if (ao == nullptr) {
665         return *this;
666     }
667 
668     for (std::size_t i = 0; i < size; i++) {
669         ao->Set(i, AAFwk::Float::Box(value[i]));
670     }
671     parameters_.SetParam(key, ao);
672     return *this;
673 }
674 
GetLongParam(const std::string & key,long defaultValue) const675 long DistributedWant::GetLongParam(const std::string& key, long defaultValue) const
676 {
677     auto value = parameters_.GetParam(key);
678     if (AAFwk::ILong::Query(value) != nullptr) {
679         return AAFwk::Long::Unbox(AAFwk::ILong::Query(value));
680     } else if (AAFwk::IString::Query(value) != nullptr) {
681         // Marshalling
682         std::string str = AAFwk::String::Unbox(AAFwk::IString::Query(value));
683         if (std::regex_match(str, NUMBER_REGEX)) {
684             return std::atoll(str.c_str());
685         }
686     }
687 
688     return defaultValue;
689 }
690 
ArrayAddData(AAFwk::IInterface * object,std::vector<long> & array)691 void ArrayAddData(AAFwk::IInterface* object, std::vector<long>& array)
692 {
693     if (object == nullptr) {
694         return;
695     }
696 
697     AAFwk::IString* o = AAFwk::IString::Query(object);
698     if (o != nullptr) {
699         std::string str = AAFwk::String::Unbox(o);
700         if (std::regex_match(str, NUMBER_REGEX)) {
701             array.push_back(std::atoll(str.c_str()));
702         }
703     }
704 }
705 
GetLongArrayParam(const std::string & key) const706 std::vector<long> DistributedWant::GetLongArrayParam(const std::string& key) const
707 {
708     std::vector<long> array;
709     auto value = parameters_.GetParam(key);
710     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
711     if (ao != nullptr && AAFwk::Array::IsLongArray(ao)) {
712         auto func = [&](AAFwk::IInterface* object) {
713             if (object != nullptr) {
714                 AAFwk::ILong* value = AAFwk::ILong::Query(object);
715                 if (value != nullptr) {
716                     array.push_back(AAFwk::Long::Unbox(value));
717                 }
718             }
719         };
720         AAFwk::Array::ForEach(ao, func);
721     } else if (ao != nullptr && AAFwk::Array::IsStringArray(ao)) {
722         // Marshalling
723         auto func = [&](AAFwk::IInterface* object) { ArrayAddData(object, array); };
724         AAFwk::Array::ForEach(ao, func);
725     }
726     return array;
727 }
728 
SetParam(const std::string & key,long value)729 DistributedWant& DistributedWant::SetParam(const std::string& key, long value)
730 {
731     parameters_.SetParam(key, AAFwk::Long::Box(value));
732     return *this;
733 }
734 
SetParam(const std::string & key,const std::vector<long> & value)735 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<long>& value)
736 {
737     std::size_t size = value.size();
738     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_ILong);
739     if (ao == nullptr) {
740         return *this;
741     }
742     for (std::size_t i = 0; i < size; i++) {
743         ao->Set(i, AAFwk::Long::Box(value[i]));
744     }
745     parameters_.SetParam(key, ao);
746     return *this;
747 }
748 
SetParam(const std::string & key,long long value)749 DistributedWant& DistributedWant::SetParam(const std::string& key, long long value)
750 {
751     parameters_.SetParam(key, AAFwk::Long::Box(value));
752     return *this;
753 }
754 
GetShortParam(const std::string & key,short defaultValue) const755 short DistributedWant::GetShortParam(const std::string& key, short defaultValue) const
756 {
757     auto value = parameters_.GetParam(key);
758     AAFwk::IShort* ao = AAFwk::IShort::Query(value);
759     if (ao != nullptr) {
760         return AAFwk::Short::Unbox(ao);
761     }
762     return defaultValue;
763 }
764 
GetShortArrayParam(const std::string & key) const765 std::vector<short> DistributedWant::GetShortArrayParam(const std::string& key) const
766 {
767     std::vector<short> array;
768     auto value = parameters_.GetParam(key);
769     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
770     if (ao != nullptr && AAFwk::Array::IsShortArray(ao)) {
771         auto func = [&](AAFwk::IInterface* object) {
772             if (object != nullptr) {
773                 AAFwk::IShort* value = AAFwk::IShort::Query(object);
774                 if (value != nullptr) {
775                     array.push_back(AAFwk::Short::Unbox(value));
776                 }
777             }
778         };
779         AAFwk::Array::ForEach(ao, func);
780     }
781     return array;
782 }
783 
SetParam(const std::string & key,short value)784 DistributedWant& DistributedWant::SetParam(const std::string& key, short value)
785 {
786     parameters_.SetParam(key, AAFwk::Short::Box(value));
787     return *this;
788 }
789 
SetParam(const std::string & key,const std::vector<short> & value)790 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<short>& value)
791 {
792     std::size_t size = value.size();
793     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IShort);
794     if (ao == nullptr) {
795         return *this;
796     }
797     for (std::size_t i = 0; i < size; i++) {
798         ao->Set(i, AAFwk::Short::Box(value[i]));
799     }
800     parameters_.SetParam(key, ao);
801     return *this;
802 }
803 
GetStringParam(const std::string & key) const804 std::string DistributedWant::GetStringParam(const std::string& key) const
805 {
806     auto value = parameters_.GetParam(key);
807     AAFwk::IString* ao = AAFwk::IString::Query(value);
808     if (ao != nullptr) {
809         return AAFwk::String::Unbox(ao);
810     }
811     return std::string();
812 }
813 
GetStringArrayParam(const std::string & key) const814 std::vector<std::string> DistributedWant::GetStringArrayParam(const std::string& key) const
815 {
816     std::vector<std::string> array;
817     auto value = parameters_.GetParam(key);
818     AAFwk::IArray* ao = AAFwk::IArray::Query(value);
819     if (ao != nullptr && AAFwk::Array::IsStringArray(ao)) {
820         auto func = [&](AAFwk::IInterface* object) {
821             if (object != nullptr) {
822                 AAFwk::IString* value = AAFwk::IString::Query(object);
823                 if (value != nullptr) {
824                     array.push_back(AAFwk::String::Unbox(value));
825                 }
826             }
827         };
828         AAFwk::Array::ForEach(ao, func);
829     }
830     return array;
831 }
832 
SetParam(const std::string & key,const std::string & value)833 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::string& value)
834 {
835     parameters_.SetParam(key, AAFwk::String::Box(value));
836     return *this;
837 }
838 
SetParam(const std::string & key,const std::vector<std::string> & value)839 DistributedWant& DistributedWant::SetParam(const std::string& key, const std::vector<std::string>& value)
840 {
841     std::size_t size = value.size();
842     sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IString);
843     if (ao == nullptr) {
844         return *this;
845     }
846     for (std::size_t i = 0; i < size; i++) {
847         ao->Set(i, AAFwk::String::Box(value[i]));
848     }
849     parameters_.SetParam(key, ao);
850     return *this;
851 }
852 
GetOperation() const853 DistributedOperation DistributedWant::GetOperation() const
854 {
855     return operation_;
856 }
857 
SetOperation(const DistributedOperation & operation)858 void DistributedWant::SetOperation(const DistributedOperation& operation)
859 {
860     operation_ = operation;
861 }
862 
OperationEquals(const DistributedWant & want)863 bool DistributedWant::OperationEquals(const DistributedWant& want)
864 {
865     return (operation_ == want.operation_);
866 }
867 
CloneOperation()868 DistributedWant* DistributedWant::CloneOperation()
869 {
870     DistributedWant* want = new (std::nothrow) DistributedWant();
871     if (want == nullptr) {
872         return nullptr;
873     }
874     want->SetOperation(operation_);
875     return want;
876 }
877 
ParseUri(const std::string & uri)878 DistributedWant* DistributedWant::ParseUri(const std::string& uri)
879 {
880     if (uri.length() <= 0) {
881         return nullptr;
882     }
883     std::string head = WANT_HEADER;
884     std::string end = ";end";
885     if (uri.find(head) != 0) {
886         return nullptr;
887     }
888     if (uri.rfind(end) != (uri.length() - end.length())) {
889         return nullptr;
890     }
891     bool ret = true;
892     std::string content;
893     std::size_t pos;
894     std::size_t begin = head.length();
895     ElementName element;
896     DistributedWant* want = new (std::nothrow) DistributedWant();
897     if (want == nullptr) {
898         return nullptr;
899     }
900     DistributedWant* baseWant = want;
901     bool inPicker = false;
902     pos = uri.find_first_of(";", begin);
903     do {
904         if (pos != std::string::npos) {
905             content = uri.substr(begin, pos - begin);
906             if (content.compare("PICK") == 0) {
907                 want = new (std::nothrow) DistributedWant();
908                 if (want == nullptr) {
909                     return nullptr;
910                 }
911                 inPicker = true;
912                 continue;
913             }
914             ret = ParseUriInternal(content, element, *want);
915             if (!ret) {
916                 break;
917             }
918             begin = pos + 1;
919             pos = uri.find(";", begin);
920             if (pos == std::string::npos) {
921                 break;
922             }
923         } else {
924             break;
925         }
926     } while (true);
927     if (inPicker) {
928         if (baseWant->GetBundle().empty()) {
929         }
930         want = baseWant;
931     }
932     if (ret) {
933         want->SetElement(element);
934     } else {
935         delete want;
936         want = nullptr;
937     }
938     return want;
939 }
940 
WantParseUri(const char * uri)941 DistributedWant* DistributedWant::WantParseUri(const char* uri)
942 {
943     if (uri == nullptr) {
944         return nullptr;
945     }
946     std::string strUri(uri);
947     return ParseUri(strUri);
948 }
949 
GetUriString() const950 std::string DistributedWant::GetUriString() const
951 {
952     return operation_.GetUri().ToString();
953 }
954 
GetUri() const955 OHOS::Uri DistributedWant::GetUri() const
956 {
957     return operation_.GetUri();
958 }
959 
SetUri(const std::string & uri)960 DistributedWant& DistributedWant::SetUri(const std::string& uri)
961 {
962     operation_.SetUri(OHOS::Uri(uri));
963     return *this;
964 }
965 
SetUri(const OHOS::Uri & uri)966 DistributedWant& DistributedWant::SetUri(const OHOS::Uri& uri)
967 {
968     operation_.SetUri(uri);
969     return *this;
970 }
971 
SetUriAndType(const OHOS::Uri & uri,const std::string & type)972 DistributedWant& DistributedWant::SetUriAndType(const OHOS::Uri& uri, const std::string& type)
973 {
974     operation_.SetUri(uri);
975     return SetType(type);
976 }
977 
WantToUri(DistributedWant & want)978 std::string DistributedWant::WantToUri(DistributedWant& want)
979 {
980     return want.ToUri();
981 }
982 
ToUri() const983 std::string DistributedWant::ToUri() const
984 {
985     std::string uriString = WANT_HEADER;
986     ToUriStringInner(uriString);
987     uriString += "end";
988     return uriString;
989 }
990 
GenerateUriString(std::string & uriString) const991 void DistributedWant::GenerateUriString(std::string& uriString) const
992 {
993     if (operation_.GetAction().length() > 0) {
994         uriString += "action=" + Encode(operation_.GetAction()) + ";";
995     }
996     if (GetUriString().length() > 0) {
997         uriString += "uri=" + Encode(GetUriString()) + ";";
998     }
999     for (auto entity : operation_.GetEntities()) {
1000         if (entity.length() > 0) {
1001             uriString += "entity=" + Encode(entity) + ";";
1002         }
1003     }
1004     if (operation_.GetDeviceId().length() > 0) {
1005         uriString += "device=" + Encode(operation_.GetDeviceId()) + ";";
1006     }
1007     if (operation_.GetBundleName().length() > 0) {
1008         uriString += "bundle=" + Encode(operation_.GetBundleName()) + ";";
1009     }
1010     if (operation_.GetAbilityName().length() > 0) {
1011         uriString += "ability=" + Encode(operation_.GetAbilityName()) + ";";
1012     }
1013     if (operation_.GetFlags() != 0) {
1014         uriString += "flag=";
1015         char buf[HEX_STRING_BUF_LEN] {0};
1016         int len = snprintf_s(buf, HEX_STRING_BUF_LEN, HEX_STRING_BUF_LEN - 1, "0x%08x", operation_.GetFlags());
1017         if (len == HEX_STRING_LEN) {
1018             std::string flag = buf;
1019             uriString += Encode(flag);
1020             uriString += ";";
1021         }
1022     }
1023     if (!operation_.GetBundleName().empty()) {
1024         uriString.append("package=");
1025         uriString.append(Encode(operation_.GetBundleName()));
1026         uriString.append(";");
1027     }
1028 }
1029 
ToUriStringInner(std::string & uriString) const1030 void DistributedWant::ToUriStringInner(std::string& uriString) const
1031 {
1032     GenerateUriString(uriString);
1033     auto params = parameters_.GetParams();
1034     auto iter = params.cbegin();
1035     while (iter != params.cend()) {
1036         sptr<AAFwk::IInterface> o = iter->second;
1037         if (AAFwk::IString::Query(o) != nullptr) {
1038             uriString += AAFwk::String::SIGNATURE;
1039         } else if (AAFwk::IBoolean::Query(o) != nullptr) {
1040             uriString += AAFwk::Boolean::SIGNATURE;
1041         } else if (AAFwk::IChar::Query(o) != nullptr) {
1042             uriString += AAFwk::Char::SIGNATURE;
1043         } else if (AAFwk::IByte::Query(o) != nullptr) {
1044             uriString += AAFwk::Byte::SIGNATURE;
1045         } else if (AAFwk::IShort::Query(o) != nullptr) {
1046             uriString += AAFwk::Short::SIGNATURE;
1047         } else if (AAFwk::IInteger::Query(o) != nullptr) {
1048             uriString += AAFwk::Integer::SIGNATURE;
1049         } else if (AAFwk::ILong::Query(o) != nullptr) {
1050             uriString += AAFwk::Long::SIGNATURE;
1051         } else if (AAFwk::IFloat::Query(o) != nullptr) {
1052             uriString += AAFwk::Float::SIGNATURE;
1053         } else if (AAFwk::IDouble::Query(o) != nullptr) {
1054             uriString += AAFwk::Double::SIGNATURE;
1055         } else if (AAFwk::IArray::Query(o) != nullptr) {
1056             uriString += AAFwk::Array::SIGNATURE;
1057         }
1058         uriString += "." + Encode(iter->first) + "=" + Encode(AAFwk::Object::ToString(*(o.GetRefPtr()))) + ";";
1059         iter++;
1060     }
1061 }
1062 
FormatUri(const std::string & uri)1063 DistributedWant& DistributedWant::FormatUri(const std::string& uri)
1064 {
1065     return FormatUri(OHOS::Uri(uri));
1066 }
1067 
FormatUri(const OHOS::Uri & uri)1068 DistributedWant& DistributedWant::FormatUri(const OHOS::Uri& uri)
1069 {
1070     operation_.SetUri(GetLowerCaseScheme(uri));
1071     return *this;
1072 }
1073 
HasParameter(const std::string & key) const1074 bool DistributedWant::HasParameter(const std::string& key) const
1075 {
1076     return parameters_.HasParam(key);
1077 }
1078 
ReplaceParams(DistributedWantParams & wantParams)1079 DistributedWant* DistributedWant::ReplaceParams(DistributedWantParams& wantParams)
1080 {
1081     parameters_ = wantParams;
1082     return this;
1083 }
1084 
ReplaceParams(DistributedWant & want)1085 DistributedWant* DistributedWant::ReplaceParams(DistributedWant& want)
1086 {
1087     parameters_ = want.parameters_;
1088     return this;
1089 }
1090 
RemoveParam(const std::string & key)1091 void DistributedWant::RemoveParam(const std::string& key)
1092 {
1093     parameters_.Remove(key);
1094 }
1095 
ClearWant(DistributedWant * want)1096 void DistributedWant::ClearWant(DistributedWant* want)
1097 {
1098     want->SetType("");
1099     want->SetAction("");
1100     want->SetFlags(0);
1101     OHOS::AppExecFwk::ElementName elementName;
1102     want->SetElement(elementName);
1103     DistributedOperation operation;
1104     want->SetOperation(operation);
1105     DistributedWantParams parameters;
1106     want->SetParams(parameters);
1107 }
1108 
MarshallingWriteUri(Parcel & parcel) const1109 bool DistributedWant::MarshallingWriteUri(Parcel& parcel) const
1110 {
1111     if (GetUriString().empty()) {
1112         if (!parcel.WriteInt32(VALUE_NULL)) {
1113             return false;
1114         }
1115     } else {
1116         if (!parcel.WriteInt32(VALUE_OBJECT)) {
1117             return false;
1118         }
1119         if (!parcel.WriteString16(Str8ToStr16(GetUriString()))) {
1120             return false;
1121         }
1122     }
1123     return true;
1124 }
1125 
MarshallingWriteEntities(Parcel & parcel) const1126 bool DistributedWant::MarshallingWriteEntities(Parcel& parcel) const
1127 {
1128     std::vector<std::u16string> entityU16;
1129     std::vector<std::string> entities = GetEntities();
1130     for (std::vector<std::string>::size_type i = 0; i < entities.size(); i++) {
1131         entityU16.push_back(Str8ToStr16(entities[i]));
1132     }
1133     if (entityU16.size() == 0) {
1134         if (!parcel.WriteInt32(VALUE_NULL)) {
1135             return false;
1136         }
1137     } else {
1138         if (!parcel.WriteInt32(VALUE_OBJECT)) {
1139             return false;
1140         }
1141         if (!parcel.WriteString16Vector(entityU16)) {
1142             return false;
1143         }
1144     }
1145     return true;
1146 }
1147 
MarshallingWriteElement(Parcel & parcel) const1148 bool DistributedWant::MarshallingWriteElement(Parcel& parcel) const
1149 {
1150     ElementName emptyElement;
1151     ElementName element = GetElement();
1152     if (element == emptyElement) {
1153         if (!parcel.WriteInt32(VALUE_NULL)) {
1154             return false;
1155         }
1156     } else {
1157         if (!parcel.WriteInt32(VALUE_OBJECT)) {
1158             return false;
1159         }
1160         if (!parcel.WriteParcelable(&element)) {
1161             return false;
1162         }
1163     }
1164     return true;
1165 }
1166 
MarshallingWriteParameters(Parcel & parcel) const1167 bool DistributedWant::MarshallingWriteParameters(Parcel& parcel) const
1168 {
1169     if (parameters_.Size() == 0) {
1170         if (!parcel.WriteInt32(VALUE_NULL)) {
1171             return false;
1172         }
1173     } else {
1174         if (!parcel.WriteInt32(VALUE_OBJECT)) {
1175             return false;
1176         }
1177         if (!parcel.WriteParcelable(&parameters_)) {
1178             return false;
1179         }
1180     }
1181     return true;
1182 }
1183 
Marshalling(Parcel & parcel) const1184 bool DistributedWant::Marshalling(Parcel& parcel) const
1185 {
1186     // write action
1187     if (!parcel.WriteString16(Str8ToStr16(GetAction()))) {
1188         return false;
1189     }
1190     // write uri
1191     if (!MarshallingWriteUri(parcel)) {
1192         return false;
1193     }
1194     // write entities
1195     if (!MarshallingWriteEntities(parcel)) {
1196         return false;
1197     }
1198     // write flags
1199     if (!parcel.WriteUint32(GetFlags())) {
1200         return false;
1201     }
1202     // write element
1203     if (!MarshallingWriteElement(parcel)) {
1204         return false;
1205     }
1206     // write parameters
1207     if (!MarshallingWriteParameters(parcel)) {
1208         return false;
1209     }
1210     // write package
1211     if (!parcel.WriteString16(Str8ToStr16(GetBundle()))) {
1212         return false;
1213     }
1214     return true;
1215 }
1216 
Unmarshalling(Parcel & parcel)1217 DistributedWant* DistributedWant::Unmarshalling(Parcel& parcel)
1218 {
1219     DistributedWant* want = new (std::nothrow) DistributedWant();
1220     if (want != nullptr && !want->ReadFromParcel(parcel)) {
1221         delete want;
1222         want = nullptr;
1223     }
1224     return want;
1225 }
1226 
ReadUriFromParcel(Parcel & parcel)1227 bool DistributedWant::ReadUriFromParcel(Parcel& parcel)
1228 {
1229     int empty = VALUE_NULL;
1230     if (!parcel.ReadInt32(empty)) {
1231         return false;
1232     }
1233     if (empty == VALUE_OBJECT) {
1234         SetUri(Str16ToStr8(parcel.ReadString16()));
1235     }
1236     return true;
1237 }
1238 
ReadEntitiesFromParcel(Parcel & parcel)1239 bool DistributedWant::ReadEntitiesFromParcel(Parcel& parcel)
1240 {
1241     std::vector<std::string> entities;
1242     std::vector<std::u16string> entityU16;
1243     int empty = VALUE_NULL;
1244     if (!parcel.ReadInt32(empty)) {
1245         return false;
1246     }
1247     if (empty == VALUE_OBJECT) {
1248         if (!parcel.ReadString16Vector(&entityU16)) {
1249             return false;
1250         }
1251     }
1252     for (std::vector<std::u16string>::size_type i = 0; i < entityU16.size(); i++) {
1253         entities.push_back(Str16ToStr8(entityU16[i]));
1254     }
1255     operation_.SetEntities(entities);
1256     return true;
1257 }
1258 
ReadElementFromParcel(Parcel & parcel)1259 bool DistributedWant::ReadElementFromParcel(Parcel& parcel)
1260 {
1261     int empty = VALUE_NULL;
1262     if (!parcel.ReadInt32(empty)) {
1263         return false;
1264     }
1265     if (empty == VALUE_OBJECT) {
1266         auto element = parcel.ReadParcelable<ElementName>();
1267         if (element != nullptr) {
1268             SetElement(*element);
1269             delete element;
1270         } else {
1271             return false;
1272         }
1273     }
1274     return true;
1275 }
1276 
ReadParametersFromParcel(Parcel & parcel)1277 bool DistributedWant::ReadParametersFromParcel(Parcel& parcel)
1278 {
1279     int empty = VALUE_NULL;
1280     if (!parcel.ReadInt32(empty)) {
1281         return false;
1282     }
1283     if (empty == VALUE_OBJECT) {
1284         auto params = parcel.ReadParcelable<DistributedWantParams>();
1285         if (params != nullptr) {
1286             parameters_ = *params;
1287             delete params;
1288             params = nullptr;
1289         } else {
1290             return false;
1291         }
1292     }
1293     return true;
1294 }
1295 
ReadFromParcel(Parcel & parcel)1296 bool DistributedWant::ReadFromParcel(Parcel& parcel)
1297 {
1298     // read action
1299     operation_.SetAction(Str16ToStr8(parcel.ReadString16()));
1300     // read uri
1301     if (!ReadUriFromParcel(parcel)) {
1302         return false;
1303     }
1304     // read entities
1305     if (!ReadEntitiesFromParcel(parcel)) {
1306         return false;
1307     }
1308     // read flags
1309     unsigned int flags;
1310     if (!parcel.ReadUint32(flags)) {
1311         return false;
1312     }
1313     operation_.SetFlags(flags);
1314     // read element
1315     if (!ReadElementFromParcel(parcel)) {
1316         return false;
1317     }
1318     // read parameters
1319     if (!ReadParametersFromParcel(parcel)) {
1320         return false;
1321     }
1322     // read package
1323     operation_.SetBundleName(Str16ToStr8(parcel.ReadString16()));
1324     return true;
1325 }
1326 
ParseUriInternal(const std::string & content,ElementName & element,DistributedWant & want)1327 bool DistributedWant::ParseUriInternal(const std::string& content, ElementName& element, DistributedWant& want)
1328 {
1329     static constexpr int TYPE_TAG_SIZE = 2;
1330     std::string prop;
1331     std::string value;
1332 
1333     if (content.empty() || content[0] == '=') {
1334         return true;
1335     }
1336     if (!ParseContent(content, prop, value)) {
1337         return false;
1338     }
1339     if (value.empty()) {
1340         return true;
1341     }
1342     if (prop == "action") {
1343         want.SetAction(value);
1344     } else if (prop == "entity") {
1345         want.AddEntity(value);
1346     } else if (prop == "flag") {
1347         if (!ParseFlag(value, want)) {
1348             return false;
1349         }
1350     } else if (prop == "device") {
1351         element.SetDeviceID(value);
1352     } else if (prop == "bundle") {
1353         element.SetBundleName(value);
1354     } else if (prop == "ability") {
1355         element.SetAbilityName(value);
1356     } else if (prop == "package") {
1357         want.SetBundle(Decode(value));
1358     } else if (prop.length() > TYPE_TAG_SIZE) {
1359         std::string key = prop.substr(TYPE_TAG_SIZE);
1360         if (!DistributedWant::CheckAndSetParameters(want, key, prop, value)) {
1361             return false;
1362         }
1363     }
1364     return true;
1365 }
1366 
ParseContent(const std::string & content,std::string & prop,std::string & value)1367 bool DistributedWant::ParseContent(const std::string& content, std::string& prop, std::string& value)
1368 {
1369     std::size_t pos = content.find("=");
1370     if (pos != std::string::npos) {
1371         std::string subString = content.substr(0, pos);
1372         prop = Decode(subString);
1373         subString = content.substr(pos + 1, content.length() - pos - 1);
1374         value = Decode(subString);
1375         return true;
1376     }
1377     return false;
1378 }
1379 
ParseFlag(const std::string & content,DistributedWant & want)1380 bool DistributedWant::ParseFlag(const std::string& content, DistributedWant& want)
1381 {
1382     std::string contentLower = LowerStr(content);
1383     std::string prefix = "0x";
1384     if (!contentLower.empty()) {
1385         if (contentLower.find(prefix) != 0) {
1386             return false;
1387         }
1388 
1389         for (std::size_t i = prefix.length(); i < contentLower.length(); i++) {
1390             if (!isxdigit(contentLower[i])) {
1391                 return false;
1392             }
1393         }
1394         int base = 16;  // hex string
1395         unsigned int flag = std::stoul(contentLower, nullptr, base);
1396         want.SetFlags(flag);
1397     }
1398     return true;
1399 }
1400 
Decode(const std::string & str)1401 std::string DistributedWant::Decode(const std::string& str)
1402 {
1403     std::string decode;
1404     for (std::size_t i = 0; i < str.length();) {
1405         if (str[i] == '\\') {
1406             if (++i >= str.length()) {
1407                 decode += "\\";
1408                 break;
1409             }
1410             if (str[i] == '\\') {
1411                 decode += "\\";
1412                 i++;
1413             } else if (str[i] == '0') {
1414                 if (str.compare(i, OCT_EQUALSTO.length(), OCT_EQUALSTO) == 0) {
1415                     decode += "=";
1416                     i += OCT_EQUALSTO.length();
1417                 } else if (str.compare(i, OCT_SEMICOLON.length(), OCT_SEMICOLON) == 0) {
1418                     decode += ";";
1419                     i += OCT_SEMICOLON.length();
1420                 } else {
1421                     decode += "\\" + str.substr(i, 1);
1422                     i++;
1423                 }
1424             } else {
1425                 decode += "\\" + str.substr(i, 1);
1426                 i++;
1427             }
1428         } else {
1429             decode += str[i];
1430             i++;
1431         }
1432     }
1433     return decode;
1434 }
1435 
Encode(const std::string & str)1436 std::string DistributedWant::Encode(const std::string& str)
1437 {
1438     std::string encode;
1439     for (std::size_t i = 0; i < str.length(); i++) {
1440         if (str[i] == '\\') {
1441             encode += "\\\\";
1442         } else if (str[i] == '=') {
1443             encode += "\\" + OCT_EQUALSTO;
1444         } else if (str[i] == ';') {
1445             encode += "\\" + OCT_SEMICOLON;
1446         } else {
1447             encode += str[i];
1448         }
1449     }
1450     return encode;
1451 }
1452 
CheckAndSetParameters(DistributedWant & want,const std::string & key,std::string & prop,const std::string & value)1453 bool DistributedWant::CheckAndSetParameters(DistributedWant& want, const std::string& key,
1454                                             std::string& prop, const std::string& value)
1455 {
1456     if (prop[0] == AAFwk::String::SIGNATURE && prop[1] == '.') {
1457         sptr<AAFwk::IString> valueObj = AAFwk::String::Parse(value);
1458         if (valueObj == nullptr) {
1459             return false;
1460         }
1461         want.parameters_.SetParam(key, valueObj);
1462     } else if (prop[0] == AAFwk::Boolean::SIGNATURE && prop[1] == '.') {
1463         sptr<AAFwk::IBoolean> valueObj = AAFwk::Boolean::Parse(value);
1464         if (valueObj == nullptr) {
1465             return false;
1466         }
1467         want.parameters_.SetParam(key, valueObj);
1468     } else if (prop[0] == AAFwk::Char::SIGNATURE && prop[1] == '.') {
1469         sptr<AAFwk::IChar> valueObj = AAFwk::Char::Parse(value);
1470         if (valueObj == nullptr) {
1471             return false;
1472         }
1473         want.parameters_.SetParam(key, valueObj);
1474     } else if (prop[0] == AAFwk::Byte::SIGNATURE && prop[1] == '.') {
1475         sptr<AAFwk::IByte> valueObj = AAFwk::Byte::Parse(value);
1476         if (valueObj == nullptr) {
1477             return false;
1478         }
1479         want.parameters_.SetParam(key, valueObj);
1480     } else if (prop[0] == AAFwk::Short::SIGNATURE && prop[1] == '.') {
1481         sptr<AAFwk::IShort> valueObj = AAFwk::Short::Parse(value);
1482         if (valueObj == nullptr) {
1483             return false;
1484         }
1485         want.parameters_.SetParam(key, valueObj);
1486     } else if (prop[0] == AAFwk::Integer::SIGNATURE && prop[1] == '.') {
1487         sptr<AAFwk::IInteger> valueObj = AAFwk::Integer::Parse(value);
1488         if (valueObj == nullptr) {
1489             return false;
1490         }
1491         want.parameters_.SetParam(key, valueObj);
1492     } else if (prop[0] == AAFwk::Long::SIGNATURE && prop[1] == '.') {
1493         sptr<AAFwk::ILong> valueObj = AAFwk::Long::Parse(value);
1494         if (valueObj == nullptr) {
1495             return false;
1496         }
1497         want.parameters_.SetParam(key, valueObj);
1498     } else if (prop[0] == AAFwk::Float::SIGNATURE && prop[1] == '.') {
1499         sptr<AAFwk::IFloat> valueObj = AAFwk::Float::Parse(value);
1500         if (valueObj == nullptr) {
1501             return false;
1502         }
1503         want.parameters_.SetParam(key, valueObj);
1504     } else if (prop[0] == AAFwk::Double::SIGNATURE && prop[1] == '.') {
1505         sptr<AAFwk::IDouble> valueObj = AAFwk::Double::Parse(value);
1506         if (valueObj == nullptr) {
1507             return false;
1508         }
1509         want.parameters_.SetParam(key, valueObj);
1510     } else if (prop[0] == AAFwk::Array::SIGNATURE && prop[1] == '.') {
1511         sptr<AAFwk::IArray> valueObj = AAFwk::Array::Parse(value);
1512         if (valueObj == nullptr) {
1513             return false;
1514         }
1515         want.parameters_.SetParam(key, valueObj);
1516     }
1517     return true;
1518 }
1519 
ToJson() const1520 nlohmann::json DistributedWant::ToJson() const
1521 {
1522     DistributedWantParamWrapper wrapper(parameters_);
1523     std::string parametersString = wrapper.ToString();
1524 
1525     nlohmann::json entitiesJson;
1526     std::vector<std::string> entities = GetEntities();
1527     for (auto entity : entities) {
1528         entitiesJson.emplace_back(entity);
1529     }
1530 
1531     nlohmann::json wantJson = nlohmann::json {
1532         {"deviceId", operation_.GetDeviceId()},
1533         {"bundleName", operation_.GetBundleName()},
1534         {"abilityName", operation_.GetAbilityName()},
1535         {"uri", GetUriString()},
1536         {"type", GetType()},
1537         {"flags", GetFlags()},
1538         {"action", GetAction()},
1539         {"parameters", parametersString},
1540         {"entities", entitiesJson},
1541     };
1542     return wantJson;
1543 }
1544 
CanReadFromJson(nlohmann::json & wantJson)1545 bool DistributedWant::CanReadFromJson(nlohmann::json& wantJson)
1546 {
1547     const auto& jsonObjectEnd = wantJson.end();
1548     if ((wantJson.find("deviceId") == jsonObjectEnd)
1549         || (wantJson.find("bundleName") == jsonObjectEnd)
1550         || (wantJson.find("abilityName") == jsonObjectEnd)
1551         || (wantJson.find("uri") == jsonObjectEnd)
1552         || (wantJson.find("type") == jsonObjectEnd)
1553         || (wantJson.find("flags") == jsonObjectEnd)
1554         || (wantJson.find("action") == jsonObjectEnd)
1555         || (wantJson.find("parameters") == jsonObjectEnd)
1556         || (wantJson.find("entities") == jsonObjectEnd)) {
1557         return false;
1558     }
1559     if (!wantJson["deviceId"].is_string()) {
1560         HILOGE("device id is not string");
1561         return false;
1562     }
1563     if (!wantJson["bundleName"].is_string()) {
1564         HILOGE("bundle name is not string");
1565         return false;
1566     }
1567     if (!wantJson["abilityName"].is_string()) {
1568         HILOGE("ability name is not string");
1569         return false;
1570     }
1571     if (!wantJson["uri"].is_string()) {
1572         HILOGE("uri is not string");
1573         return false;
1574     }
1575     if (!wantJson["type"].is_string()) {
1576         HILOGE("type is not string");
1577         return false;
1578     }
1579     if (!wantJson["flags"].is_number_unsigned()) {
1580         HILOGE("flags is not a number");
1581         return false;
1582     }
1583     if (!wantJson["action"].is_string()) {
1584         HILOGE("action is not string");
1585         return false;
1586     }
1587     if (!wantJson["parameters"].is_string()) {
1588         HILOGE("parameters is not string");
1589         return false;
1590     }
1591     return true;
1592 }
1593 
ReadFromJson(nlohmann::json & wantJson)1594 bool DistributedWant::ReadFromJson(nlohmann::json& wantJson)
1595 {
1596     if (!CanReadFromJson(wantJson)) {
1597         HILOGE("can not read from json");
1598         return false;
1599     }
1600     std::string deviceId = wantJson.at("deviceId").get<std::string>();
1601     std::string bundleName = wantJson.at("bundleName").get<std::string>();
1602     std::string abilityName = wantJson.at("abilityName").get<std::string>();
1603     SetElementName(deviceId, bundleName, abilityName);
1604 
1605     std::string uri = wantJson.at("uri").get<std::string>();
1606     SetUri(uri);
1607 
1608     std::string type = wantJson.at("type").get<std::string>();
1609     SetType(type);
1610 
1611     unsigned int flags = wantJson.at("flags").get<unsigned int>();
1612     SetFlags(flags);
1613 
1614     std::string action = wantJson.at("action").get<std::string>();
1615     SetAction(action);
1616 
1617     std::string parametersString = wantJson.at("parameters").get<std::string>();
1618     DistributedWantParams parameters = DistributedWantParamWrapper::ParseWantParams(parametersString);
1619     SetParams(parameters);
1620     if (!wantJson.at("entities").is_null()) {
1621         std::vector<std::string> entities;
1622         wantJson.at("entities").get_to<std::vector<std::string>>(entities);
1623         for (size_t i = 0; i < entities.size(); i++) {
1624             AddEntity(entities[i]);
1625         }
1626     }
1627     return true;
1628 }
1629 
ToString() const1630 std::string DistributedWant::ToString() const
1631 {
1632     return ToJson().dump();
1633 }
1634 
FromString(std::string & string)1635 DistributedWant* DistributedWant::FromString(std::string& string)
1636 {
1637     if (string.empty()) {
1638         return nullptr;
1639     }
1640 
1641     nlohmann::json wantJson = nlohmann::json::parse(string);
1642 
1643     DistributedWant* want = new (std::nothrow) DistributedWant();
1644     if (want != nullptr && !want->ReadFromJson(wantJson)) {
1645         delete want;
1646         want = nullptr;
1647     }
1648     return want;
1649 }
1650 
SetDeviceId(const std::string & deviceId)1651 DistributedWant& DistributedWant::SetDeviceId(const std::string& deviceId)
1652 {
1653     operation_.SetDeviceId(deviceId);
1654     return *this;
1655 }
1656 } // namespace DistributedSchedule
1657 } // namespace OHOS
1658