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(¶meters_)) {
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