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