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
43using namespace OHOS::AppExecFwk;
44using OHOS::AppExecFwk::ElementName;
45namespace OHOS {
46namespace DistributedSchedule {
47namespace {
48const std::regex NUMBER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$");
49const std::string TAG = "DistributedWant";
50const char* TYPE_PROPERTY = "type";
51};  // namespace
52const std::string DistributedWant::ACTION_PLAY("action.system.play");
53const std::string DistributedWant::ACTION_HOME("action.system.home");
54
55const std::string DistributedWant::ENTITY_HOME("entity.system.home");
56const std::string DistributedWant::ENTITY_VIDEO("entity.system.video");
57const std::string DistributedWant::FLAG_HOME_INTENT_FROM_SYSTEM("flag.home.intent.from.system");
58const std::string DistributedWant::ENTITY_MUSIC("entity.app.music");
59const std::string DistributedWant::ENTITY_EMAIL("entity.app.email");
60const std::string DistributedWant::ENTITY_CONTACTS("entity.app.contacts");
61const std::string DistributedWant::ENTITY_MAPS("entity.app.maps");
62const std::string DistributedWant::ENTITY_BROWSER("entity.app.browser");
63const std::string DistributedWant::ENTITY_CALENDAR("entity.app.calendar");
64const std::string DistributedWant::ENTITY_MESSAGING("entity.app.messaging");
65const std::string DistributedWant::ENTITY_FILES("entity.app.files");
66const std::string DistributedWant::ENTITY_GALLERY("entity.app.gallery");
67
68const std::string DistributedWant::OCT_EQUALSTO("075");   // '='
69const std::string DistributedWant::OCT_SEMICOLON("073");  // ';'
70const std::string DistributedWant::MIME_TYPE("mime-type");
71const std::string DistributedWant::WANT_HEADER("#Intent;");
72
73const std::string DistributedWant::PARAM_RESV_WINDOW_MODE("ohos.aafwk.param.windowMode");
74const std::string DistributedWant::PARAM_RESV_DISPLAY_ID("ohos.aafwk.param.displayId");
75const std::string DistributedWant::PARAM_RESV_CALLER_TOKEN("ohos.aafwk.param.callerToken");
76const std::string DistributedWant::PARAM_RESV_CALLER_UID("ohos.aafwk.param.callerUid");
77const std::string DistributedWant::PARAM_RESV_CALLER_PID("ohos.aafwk.param.callerPid");
78
79DistributedWant::DistributedWant()
80{}
81
82DistributedWant::~DistributedWant()
83{}
84
85DistributedWant::DistributedWant(const DistributedWant& other)
86{
87    operation_ = other.operation_;
88    parameters_ = other.parameters_;
89}
90
91DistributedWant& DistributedWant::operator=(const DistributedWant& other)
92{
93    operation_ = other.operation_;
94    parameters_ = other.parameters_;
95    return *this;
96}
97
98DistributedWant::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
130std::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
147unsigned int DistributedWant::GetFlags() const
148{
149    return operation_.GetFlags();
150}
151
152DistributedWant& DistributedWant::SetFlags(unsigned int flags)
153{
154    operation_.SetFlags(flags);
155    return *this;
156}
157
158DistributedWant& DistributedWant::AddFlags(unsigned int flags)
159{
160    operation_.AddFlags(flags);
161    return *this;
162}
163
164void DistributedWant::RemoveFlags(unsigned int flags)
165{
166    operation_.RemoveFlags(flags);
167}
168
169OHOS::AppExecFwk::ElementName DistributedWant::GetElement() const
170{
171    return ElementName(operation_.GetDeviceId(), operation_.GetBundleName(), operation_.GetAbilityName());
172}
173
174DistributedWant& DistributedWant::SetElementName(const std::string& bundleName, const std::string& abilityName)
175{
176    operation_.SetBundleName(bundleName);
177    operation_.SetAbilityName(abilityName);
178    return *this;
179}
180
181DistributedWant& 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
190DistributedWant& 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
198const std::vector<std::string>& DistributedWant::GetEntities() const
199{
200    return operation_.GetEntities();
201}
202
203DistributedWant& DistributedWant::AddEntity(const std::string& entity)
204{
205    operation_.AddEntity(entity);
206    return *this;
207}
208
209void DistributedWant::RemoveEntity(const std::string& entity)
210{
211    operation_.RemoveEntity(entity);
212}
213
214bool DistributedWant::HasEntity(const std::string& entity) const
215{
216    return operation_.HasEntity(entity);
217}
218
219int DistributedWant::CountEntities()
220{
221    return operation_.CountEntities();
222}
223
224std::string DistributedWant::GetBundle() const
225{
226    return operation_.GetBundleName();
227}
228
229DistributedWant& DistributedWant::SetBundle(const std::string& bundleName)
230{
231    operation_.SetBundleName(bundleName);
232    return *this;
233}
234
235std::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
245DistributedWant& 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
252Uri 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
277std::string DistributedWant::GetAction() const
278{
279    return operation_.GetAction();
280}
281
282DistributedWant& DistributedWant::SetAction(const std::string& action)
283{
284    operation_.SetAction(action);
285    return *this;
286}
287
288const std::string DistributedWant::GetScheme() const
289{
290    return operation_.GetUri().GetScheme();
291}
292
293const DistributedWantParams& DistributedWant::GetParams() const
294{
295    return parameters_;
296}
297
298DistributedWant& DistributedWant::SetParams(const DistributedWantParams& wantParams)
299{
300    parameters_ = wantParams;
301    return *this;
302}
303
304bool 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
314std::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
333DistributedWant& 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
342DistributedWant& DistributedWant::SetParam(const std::string& key, bool value)
343{
344    parameters_.SetParam(key, AAFwk::Boolean::Box(value));
345    return *this;
346}
347
348DistributedWant& 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
361AAFwk::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
371std::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
390DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::byte value)
391{
392    parameters_.SetParam(key, AAFwk::Byte::Box(value));
393    return *this;
394}
395
396DistributedWant& 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
410AAFwk::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
420std::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
439DistributedWant& DistributedWant::SetParam(const std::string& key, AAFwk::zchar value)
440{
441    parameters_.SetParam(key, AAFwk::Char::Box(value));
442    return *this;
443}
444
445DistributedWant& 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
459int 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
469std::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
488DistributedWant& DistributedWant::SetParam(const std::string& key, int value)
489{
490    parameters_.SetParam(key, AAFwk::Integer::Box(value));
491    return *this;
492}
493
494DistributedWant& 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
508double 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
518std::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
537DistributedWant& DistributedWant::SetParam(const std::string& key, double value)
538{
539    parameters_.SetParam(key, AAFwk::Double::Box(value));
540    return *this;
541}
542
543DistributedWant& 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
557float 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
567std::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
586DistributedWant& DistributedWant::SetParam(const std::string& key, float value)
587{
588    parameters_.SetParam(key, AAFwk::Float::Box(value));
589    return *this;
590}
591
592DistributedWant& 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
607long 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
623void 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
638std::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
661DistributedWant& DistributedWant::SetParam(const std::string& key, long value)
662{
663    parameters_.SetParam(key, AAFwk::Long::Box(value));
664    return *this;
665}
666
667DistributedWant& 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
681DistributedWant& DistributedWant::SetParam(const std::string& key, long long value)
682{
683    parameters_.SetParam(key, AAFwk::Long::Box(value));
684    return *this;
685}
686
687short 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
697std::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
716DistributedWant& DistributedWant::SetParam(const std::string& key, short value)
717{
718    parameters_.SetParam(key, AAFwk::Short::Box(value));
719    return *this;
720}
721
722DistributedWant& 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
736std::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
746std::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
765DistributedWant& DistributedWant::SetParam(const std::string& key, const std::string& value)
766{
767    parameters_.SetParam(key, AAFwk::String::Box(value));
768    return *this;
769}
770
771DistributedWant& 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
785DistributedOperation DistributedWant::GetOperation() const
786{
787    return operation_;
788}
789
790void DistributedWant::SetOperation(const DistributedOperation& operation)
791{
792    operation_ = operation;
793}
794
795bool DistributedWant::OperationEquals(const DistributedWant& want)
796{
797    return (operation_ == want.operation_);
798}
799
800std::string DistributedWant::GetUriString() const
801{
802    return operation_.GetUri().ToString();
803}
804
805OHOS::Uri DistributedWant::GetUri() const
806{
807    return operation_.GetUri();
808}
809
810DistributedWant& DistributedWant::SetUri(const std::string& uri)
811{
812    operation_.SetUri(OHOS::Uri(uri));
813    return *this;
814}
815
816DistributedWant& DistributedWant::SetUri(const OHOS::Uri& uri)
817{
818    operation_.SetUri(uri);
819    return *this;
820}
821
822DistributedWant& DistributedWant::SetUriAndType(const OHOS::Uri& uri, const std::string& type)
823{
824    operation_.SetUri(uri);
825    return SetType(type);
826}
827
828DistributedWant& DistributedWant::FormatUri(const std::string& uri)
829{
830    return FormatUri(OHOS::Uri(uri));
831}
832
833DistributedWant& DistributedWant::FormatUri(const OHOS::Uri& uri)
834{
835    operation_.SetUri(GetLowerCaseScheme(uri));
836    return *this;
837}
838
839bool DistributedWant::HasParameter(const std::string& key) const
840{
841    return parameters_.HasParam(key);
842}
843
844DistributedWant* DistributedWant::ReplaceParams(DistributedWantParams& wantParams)
845{
846    parameters_ = wantParams;
847    return this;
848}
849
850DistributedWant* DistributedWant::ReplaceParams(DistributedWant& want)
851{
852    parameters_ = want.parameters_;
853    return this;
854}
855
856void DistributedWant::RemoveParam(const std::string& key)
857{
858    parameters_.Remove(key);
859}
860
861void 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
877bool 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
897bool 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
919bool 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
938bool DistributedWant::MarshallingWriteParameters(Parcel& parcel) const
939{
940    if (parameters_.Size() == 0) {
941        if (!parcel.WriteInt32(VALUE_NULL)) {
942            return false;
943        }
944        return true;
945    }
946
947    if (!parcel.WriteInt32(VALUE_OBJECT)) {
948        return false;
949    }
950
951    if (!parcel.WriteParcelable(&parameters_)) {
952        return false;
953    }
954    return true;
955}
956
957bool 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
990DistributedWant* 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
1000bool 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
1012bool 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
1032bool 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
1050bool 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
1069bool 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
1100nlohmann::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
1125bool 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
1174bool 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
1223std::string DistributedWant::ToString() const
1224{
1225    return ToJson().dump();
1226}
1227
1228DistributedWant* 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
1247DistributedWant& DistributedWant::SetDeviceId(const std::string& deviceId)
1248{
1249    operation_.SetDeviceId(deviceId);
1250    return *this;
1251}
1252} // namespace DistributedSchedule
1253} // namespace OHOS
1254