• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "want_params.h"
17 #ifndef WANT_PARAM_USE_LONG
18 #define WANT_PARAM_USE_LONG
19 #endif
20 
21 #include "ability_base_log_wrapper.h"
22 #include "base_interfaces.h"
23 #include "base_obj.h"
24 #include "bool_wrapper.h"
25 #include "byte_wrapper.h"
26 #include "double_wrapper.h"
27 #include "float_wrapper.h"
28 #include "int_wrapper.h"
29 #include "long_wrapper.h"
30 #include "short_wrapper.h"
31 #include "string_wrapper.h"
32 #include "zchar_wrapper.h"
33 #include "remote_object_wrapper.h"
34 #include "array_wrapper.h"
35 #include "want_params_wrapper.h"
36 #include "parcel.h"
37 #include "securec.h"
38 #include "string_ex.h"
39 
40 namespace OHOS {
41 namespace AAFwk {
42 const char* FD = "FD";
43 const char* REMOTE_OBJECT = "RemoteObject";
44 const char* TYPE_PROPERTY = "type";
45 const char* VALUE_PROPERTY = "value";
46 constexpr int32_t MAX_RECURSION_DEPTH = 100;
~UnsupportedData()47 UnsupportedData::~UnsupportedData()
48 {
49     if (buffer != nullptr) {
50         delete[] buffer;
51         buffer = nullptr;
52     }
53 }
54 
55 UnsupportedData::UnsupportedData() = default;
56 
UnsupportedData(const UnsupportedData & other)57 UnsupportedData::UnsupportedData(const UnsupportedData &other) : key(other.key), type(other.type), size(other.size)
58 {
59     buffer = new uint8_t[size];
60     if (memcpy_s(buffer, size, other.buffer, size) != EOK) {
61         ABILITYBASE_LOGE("memcpy failed");
62 
63         key.clear();
64         type = 0;
65         size = 0;
66         delete[] buffer;
67         buffer = nullptr;
68     }
69 }
70 
UnsupportedData(UnsupportedData && other)71 UnsupportedData::UnsupportedData(UnsupportedData &&other)
72     : key(std::move(other.key)), type(other.type), size(other.size), buffer(other.buffer)
73 {
74     other.type = 0;
75     other.size = 0;
76     other.buffer = nullptr;
77 }
78 
operator =(const UnsupportedData & other)79 UnsupportedData &UnsupportedData::operator=(const UnsupportedData &other)
80 {
81     if (this == &other) {
82         return *this;
83     }
84     key = other.key;
85     type = other.type;
86     size = other.size;
87     if (buffer != nullptr) {
88         ABILITYBASE_LOGI("clean buffer");
89         delete[] buffer;
90         buffer = nullptr;
91     }
92     buffer = new uint8_t[size];
93     if (memcpy_s(buffer, size, other.buffer, size) != EOK) {
94         ABILITYBASE_LOGE("memcpy failed");
95 
96         key.clear();
97         type = 0;
98         size = 0;
99         delete[] buffer;
100         buffer = nullptr;
101     }
102     return *this;
103 }
104 
operator =(UnsupportedData && other)105 UnsupportedData &UnsupportedData::operator=(UnsupportedData &&other)
106 {
107     key = std::move(other.key);
108     type = other.type;
109     size = other.size;
110     std::swap(buffer, other.buffer);
111 
112     other.type = 0;
113     other.size = 0;
114     if (other.buffer) {
115         delete[] other.buffer;
116         other.buffer = nullptr;
117     }
118     return *this;
119 }
120 
GetStringByType(const sptr<IInterface> iIt,int typeId)121 std::string WantParams::GetStringByType(const sptr<IInterface> iIt, int typeId)
122 {
123     if (GetDataType(iIt) != typeId) {
124         return "";
125     }
126     if (typeId == VALUE_TYPE_BOOLEAN) {
127         return static_cast<Boolean *>(IBoolean::Query(iIt))->ToString();
128     } else if (typeId == VALUE_TYPE_BYTE) {
129         return static_cast<Byte *>(IByte::Query(iIt))->ToString();
130     } else if (typeId == VALUE_TYPE_CHAR) {
131         return static_cast<Char *>(IChar::Query(iIt))->ToString();
132     } else if (typeId == VALUE_TYPE_SHORT) {
133         return static_cast<Short *>(IShort::Query(iIt))->ToString();
134     } else if (typeId == VALUE_TYPE_INT) {
135         return static_cast<Integer *>(IInteger::Query(iIt))->ToString();
136     } else if (typeId == VALUE_TYPE_LONG) {
137         return static_cast<Long *>(ILong::Query(iIt))->ToString();
138     } else if (typeId == VALUE_TYPE_FLOAT) {
139         return static_cast<Float *>(IFloat::Query(iIt))->ToString();
140     } else if (typeId == VALUE_TYPE_DOUBLE) {
141         return static_cast<Double *>(IDouble::Query(iIt))->ToString();
142     } else if (typeId == VALUE_TYPE_STRING) {
143         return static_cast<String *>(IString::Query(iIt))->ToString();
144     } else if (typeId == VALUE_TYPE_ARRAY) {
145         return static_cast<Array *>(IArray::Query(iIt))->ToString();
146     } else if (typeId == VALUE_TYPE_WANTPARAMS) {
147         return static_cast<WantParamWrapper *>(IWantParams::Query(iIt))->ToString();
148     } else {
149         return "";
150     }
151     return "";
152 }
153 template<typename T1, typename T2, typename T3>
154 static void SetNewArray(const AAFwk::InterfaceID &id, AAFwk::IArray *orgIArray, sptr<AAFwk::IArray> &ao);
155 /**
156  * @description: A constructor used to create an WantParams instance by using the parameters of an existing
157  * WantParams object.
158  * @param wantParams  Indicates the existing WantParams object.
159  */
WantParams(const WantParams & wantParams)160 WantParams::WantParams(const WantParams &wantParams)
161 {
162     params_.clear();
163     NewParams(wantParams, *this);
164 }
165 
WantParams(WantParams && other)166 WantParams::WantParams(WantParams && other) noexcept
167 {
168     *this = std::move(other);
169 }
170 
171 // inner use function
NewFds(const WantParams & source,WantParams & dest)172 bool WantParams::NewFds(const WantParams &source, WantParams &dest)
173 {
174     // Deep copy
175     for (auto it : source.fds_) {
176         dest.fds_[it.first] = it.second;
177     }
178     return true;
179 }  // namespace AAFwk
180 
181 // inner use function
NewParams(const WantParams & source,WantParams & dest)182 bool WantParams::NewParams(const WantParams &source, WantParams &dest)
183 {
184     // Deep copy
185     for (auto it = source.params_.begin(); it != source.params_.end(); it++) {
186         sptr<IInterface> o = it->second;
187         if (IString::Query(o) != nullptr) {
188             dest.params_[it->first] = String::Box(String::Unbox(IString::Query(o)));
189         } else if (IBoolean::Query(o) != nullptr) {
190             dest.params_[it->first] = Boolean::Box(Boolean::Unbox(IBoolean::Query(o)));
191         } else if (IByte::Query(o) != nullptr) {
192             dest.params_[it->first] = Byte::Box(Byte::Unbox(IByte::Query(o)));
193         } else if (IChar::Query(o) != nullptr) {
194             dest.params_[it->first] = Char::Box(Char::Unbox(IChar::Query(o)));
195         } else if (IShort::Query(o) != nullptr) {
196             dest.params_[it->first] = Short::Box(Short::Unbox(IShort::Query(o)));
197         } else if (IInteger::Query(o) != nullptr) {
198             dest.params_[it->first] = Integer::Box(Integer::Unbox(IInteger::Query(o)));
199         } else if (ILong::Query(o) != nullptr) {
200             dest.params_[it->first] = Long::Box(Long::Unbox(ILong::Query(o)));
201         } else if (IFloat::Query(o) != nullptr) {
202             dest.params_[it->first] = Float::Box(Float::Unbox(IFloat::Query(o)));
203         } else if (IDouble::Query(o) != nullptr) {
204             dest.params_[it->first] = Double::Box(Double::Unbox(IDouble::Query(o)));
205         } else if (IRemoteObjectWrap::Query(o) != nullptr) {
206             dest.params_[it->first] = RemoteObjectWrap::Box(RemoteObjectWrap::UnBox(IRemoteObjectWrap::Query(o)));
207         } else if (IWantParams::Query(o) != nullptr) {
208             dest.params_[it->first] = WantParamWrapper::Box(WantParamWrapper::Unbox(IWantParams::Query(o)));
209         } else if (IArray::Query(o) != nullptr) {
210             sptr<IArray> destAO = nullptr;
211             if (!NewArrayData(IArray::Query(o), destAO)) {
212                 continue;
213             }
214             dest.params_[it->first] = destAO;
215         }
216     }
217     return true;
218 }  // namespace AAFwk
219 // inner use
NewArrayData(IArray * source,sptr<IArray> & dest)220 bool WantParams::NewArrayData(IArray *source, sptr<IArray> &dest)
221 {
222     if (Array::IsBooleanArray(source)) {
223         SetNewArray<bool, AAFwk::Boolean, AAFwk::IBoolean>(AAFwk::g_IID_IBoolean, source, dest);
224     } else if (Array::IsCharArray(source)) {
225         SetNewArray<char, AAFwk::Char, AAFwk::IChar>(AAFwk::g_IID_IChar, source, dest);
226     } else if (Array::IsByteArray(source)) {
227         SetNewArray<byte, AAFwk::Byte, AAFwk::IByte>(AAFwk::g_IID_IByte, source, dest);
228     } else if (Array::IsShortArray(source)) {
229         SetNewArray<short, AAFwk::Short, AAFwk::IShort>(AAFwk::g_IID_IShort, source, dest);
230     } else if (Array::IsIntegerArray(source)) {
231         SetNewArray<int, AAFwk::Integer, AAFwk::IInteger>(AAFwk::g_IID_IInteger, source, dest);
232     } else if (Array::IsLongArray(source)) {
233         SetNewArray<long, AAFwk::Long, AAFwk::ILong>(AAFwk::g_IID_ILong, source, dest);
234     } else if (Array::IsFloatArray(source)) {
235         SetNewArray<float, AAFwk::Float, AAFwk::IFloat>(AAFwk::g_IID_IFloat, source, dest);
236     } else if (Array::IsDoubleArray(source)) {
237         SetNewArray<double, AAFwk::Double, AAFwk::IDouble>(AAFwk::g_IID_IDouble, source, dest);
238     } else if (Array::IsStringArray(source)) {
239         SetNewArray<std::string, AAFwk::String, AAFwk::IString>(AAFwk::g_IID_IString, source, dest);
240     } else if (Array::IsWantParamsArray(source)) {
241         SetNewArray<WantParams, AAFwk::WantParamWrapper, AAFwk::IWantParams>(AAFwk::g_IID_IWantParams, source, dest);
242     } else {
243         return false;
244     }
245 
246     if (dest == nullptr) {
247         return false;
248     }
249 
250     return true;
251 }
252 /**
253  * @description: A WantParams used to
254  *
255  * @param other  Indicates the existing WantParams object.
256  */
operator =(const WantParams & other)257 WantParams &WantParams::operator=(const WantParams &other)
258 {
259     if (this != &other) {
260         params_.clear();
261         fds_.clear();
262         NewParams(other, *this);
263         NewFds(other, *this);
264         cachedUnsupportedData_.clear();
265         cachedUnsupportedData_ = other.cachedUnsupportedData_;
266     }
267     return *this;
268 }
269 
operator =(WantParams && other)270 WantParams &WantParams::operator=(WantParams &&other) noexcept
271 {
272     if (this != &other) {
273         // free existing resources.
274         params_.clear();
275         params_ = other.params_;
276         // free other resources.
277         other.params_.clear();
278         fds_.clear();
279         fds_ = other.fds_;
280         other.fds_.clear();
281         cachedUnsupportedData_.clear();
282         cachedUnsupportedData_ = other.cachedUnsupportedData_;
283         other.cachedUnsupportedData_.clear();
284     }
285     return *this;
286 }
287 
operator ==(const WantParams & other)288 bool WantParams::operator==(const WantParams &other)
289 {
290     if (this->params_.size() != other.params_.size()) {
291         return false;
292     }
293     for (auto itthis : this->params_) {
294         auto itother = other.params_.find(itthis.first);
295         if (itother == other.params_.end()) {
296             return false;
297         }
298         int type1 = WantParams::GetDataType(itthis.second);
299         int type2 = WantParams::GetDataType(itother->second);
300         if (type1 != type2) {
301             return false;
302         }
303         if (!CompareInterface(itother->second, itthis.second, type1)) {
304             return false;
305         }
306     }
307     return true;
308 }
309 
GetDataType(const sptr<IInterface> iIt)310 int WantParams::GetDataType(const sptr<IInterface> iIt)
311 {
312     if (iIt == nullptr) {
313         return VALUE_TYPE_NULL;
314     }
315     if (IBoolean::Query(iIt) != nullptr) {
316         return VALUE_TYPE_BOOLEAN;
317     } else if (IByte::Query(iIt) != nullptr) {
318         return VALUE_TYPE_BYTE;
319     } else if (IChar::Query(iIt) != nullptr) {
320         return VALUE_TYPE_CHAR;
321     } else if (IShort::Query(iIt) != nullptr) {
322         return VALUE_TYPE_SHORT;
323     } else if (IInteger::Query(iIt) != nullptr) {
324         return VALUE_TYPE_INT;
325     } else if (ILong::Query(iIt) != nullptr) {
326         return VALUE_TYPE_LONG;
327     } else if (IFloat::Query(iIt) != nullptr) {
328         return VALUE_TYPE_FLOAT;
329     } else if (IDouble::Query(iIt) != nullptr) {
330         return VALUE_TYPE_DOUBLE;
331     } else if (IString::Query(iIt) != nullptr) {
332         return VALUE_TYPE_STRING;
333     } else if (IArray::Query(iIt) != nullptr) {
334         return VALUE_TYPE_ARRAY;
335     } else if (IWantParams::Query(iIt) != nullptr) {
336         return VALUE_TYPE_WANTPARAMS;
337     }
338 
339     return VALUE_TYPE_NULL;
340 }
341 
GetInterfaceByType(int typeId,const std::string & value)342 sptr<IInterface> WantParams::GetInterfaceByType(int typeId, const std::string &value)
343 {
344     if (typeId == VALUE_TYPE_BOOLEAN) {
345         return Boolean::Parse(value);
346     } else if (typeId == VALUE_TYPE_BYTE) {
347         return Byte::Parse(value);
348     } else if (typeId == VALUE_TYPE_CHAR) {
349         return Char::Parse(value);
350     } else if (typeId == VALUE_TYPE_SHORT) {
351         return Short::Parse(value);
352     } else if (typeId == VALUE_TYPE_INT) {
353         return Integer::Parse(value);
354     } else if (typeId == VALUE_TYPE_LONG) {
355         return Long::Parse(value);
356     } else if (typeId == VALUE_TYPE_FLOAT) {
357         return Float::Parse(value);
358     } else if (typeId == VALUE_TYPE_DOUBLE) {
359         return Double::Parse(value);
360     } else if (typeId == VALUE_TYPE_STRING) {
361         return String::Parse(value);
362     } else if (typeId == VALUE_TYPE_ARRAY) {
363         return Array::Parse(value);
364     }
365 
366     return nullptr;
367 }
368 
CompareInterface(const sptr<IInterface> iIt1,const sptr<IInterface> iIt2,int typeId)369 bool WantParams::CompareInterface(const sptr<IInterface> iIt1, const sptr<IInterface> iIt2, int typeId)
370 {
371     auto typeId1 = GetDataType(iIt1);
372     if (typeId1 != GetDataType(iIt2) || typeId1 != typeId) {
373         return false;
374     }
375     bool flag = true;
376     switch (typeId) {
377         case VALUE_TYPE_BOOLEAN:
378             flag =
379                 static_cast<Boolean *>(IBoolean::Query(iIt1))->Equals(*(static_cast<Boolean *>(IBoolean::Query(iIt2))));
380             break;
381         case VALUE_TYPE_BYTE:
382             flag = static_cast<Byte *>(IByte::Query(iIt1))->Equals(*(static_cast<Byte *>(IByte::Query(iIt2))));
383             break;
384         case VALUE_TYPE_CHAR:
385             flag = static_cast<Char *>(IChar::Query(iIt1))->Equals(*(static_cast<Char *>(IChar::Query(iIt2))));
386             break;
387         case VALUE_TYPE_SHORT:
388             flag = static_cast<Short *>(IShort::Query(iIt1))->Equals(*(static_cast<Short *>(IShort::Query(iIt2))));
389             break;
390         case VALUE_TYPE_INT:
391             flag =
392                 static_cast<Integer *>(IInteger::Query(iIt1))->Equals(*(static_cast<Integer *>(IInteger::Query(iIt2))));
393             break;
394         case VALUE_TYPE_LONG:
395             flag = static_cast<Long *>(ILong::Query(iIt1))->Equals(*(static_cast<Long *>(ILong::Query(iIt2))));
396             break;
397         case VALUE_TYPE_FLOAT:
398             flag = static_cast<Float *>(IFloat::Query(iIt1))->Equals(*(static_cast<Float *>(IFloat::Query(iIt2))));
399             break;
400         case VALUE_TYPE_DOUBLE:
401             flag = static_cast<Double *>(IDouble::Query(iIt1))->Equals(*(static_cast<Double *>(IDouble::Query(iIt2))));
402             break;
403         case VALUE_TYPE_STRING:
404             flag = static_cast<String *>(IString::Query(iIt1))->Equals(*(static_cast<String *>(IString::Query(iIt2))));
405             break;
406         case VALUE_TYPE_ARRAY:
407             flag = static_cast<Array *>(IArray::Query(iIt1))->Equals(*(static_cast<Array *>(IArray::Query(iIt2))));
408             break;
409         case VALUE_TYPE_WANTPARAMS:
410             flag = static_cast<WantParamWrapper *>(IWantParams::Query(iIt1))->
411                 Equals(*(static_cast<WantParamWrapper *>(IWantParams::Query(iIt2))));
412             break;
413         default:
414             break;
415     }
416     return flag;
417 }
418 
419 /**
420  * @description: Sets a parameter in key-value pair format.
421  * @param key Indicates the key matching the parameter.
422  */
SetParam(const std::string & key,IInterface * value)423 void WantParams::SetParam(const std::string &key, IInterface *value)
424 {
425     params_[key] = value;
426 }
427 
428 /**
429  * @description: Obtains the parameter value based on a given key.
430  * @param key Indicates the key matching the parameter.
431  * @return Returns the value matching the given key.
432  */
GetParam(const std::string & key) const433 sptr<IInterface> WantParams::GetParam(const std::string &key) const
434 {
435     auto it = params_.find(key);
436     if (it == params_.cend()) {
437         return nullptr;
438     }
439     return it->second;
440 }
441 
GetWantParams(const std::string & key) const442 WantParams WantParams::GetWantParams(const std::string& key) const
443 {
444     auto value = GetParam(key);
445     IWantParams *wp = IWantParams::Query(value);
446     if (wp != nullptr) {
447         return WantParamWrapper::Unbox(wp);
448     }
449     return WantParams();
450 }
451 
GetStringParam(const std::string & key) const452 std::string WantParams::GetStringParam(const std::string& key) const
453 {
454     auto value = GetParam(key);
455     IString *ao = IString::Query(value);
456     if (ao != nullptr) {
457         return String::Unbox(ao);
458     }
459     return std::string();
460 }
461 
GetIntParam(const std::string & key,const int defaultValue) const462 int WantParams::GetIntParam(const std::string& key, const int defaultValue) const
463 {
464     ABILITYBASE_LOGD("called");
465     auto value = GetParam(key);
466     IInteger *ao = IInteger::Query(value);
467     if (ao != nullptr) {
468         return Integer::Unbox(ao);
469     }
470     return defaultValue;
471 }
472 
473 /**
474  * @description: Obtains the parameter value based on a given key.
475  * @param key Indicates the key matching the parameter.
476  * @return Returns the value matching the given key.
477  */
478 
GetParams() const479 const std::map<std::string, sptr<IInterface>> &WantParams::GetParams() const
480 {
481     return params_;
482 }
483 
484 /**
485  * @description: Obtains a set of the keys of all parameters.
486  * @param
487  * @return Returns a set of keys.
488  */
KeySet() const489 const std::set<std::string> WantParams::KeySet() const
490 {
491     std::set<std::string> keySet;
492     keySet.clear();
493     for (auto it : params_) {
494         keySet.emplace(it.first);
495     }
496 
497     return keySet;
498 }
499 
500 /**
501  * @description: Removes the parameter matching the given key.
502  * @param key Indicates the key matching the parameter to be removed.
503  */
Remove(const std::string & key)504 void WantParams::Remove(const std::string &key)
505 {
506     params_.erase(key);
507 }
508 
509 /**
510  * @description: Checks whether the Want contains the given key.
511  * @param key Indicates the key to check.
512  * @return Returns true if the Want contains the key; returns false otherwise.
513  */
HasParam(const std::string & key) const514 bool WantParams::HasParam(const std::string &key) const
515 {
516     return (params_.count(key) > 0);
517 }
518 
519 /**
520  * @description: Obtains the number of parameters contained in this WantParams object.
521  * @return Returns the number of parameters.
522  */
Size() const523 int WantParams::Size() const
524 {
525     return params_.size();
526 }
527 
528 /**
529  * @description: Checks whether this WantParams object contains no parameters.
530  * @return Returns true if this object does not contain any parameters; returns false otherwise.
531  */
IsEmpty() const532 bool WantParams::IsEmpty() const
533 {
534     return (params_.size() == 0);
535 }
536 
WriteToParcelString(Parcel & parcel,sptr<IInterface> & o) const537 bool WantParams::WriteToParcelString(Parcel &parcel, sptr<IInterface> &o) const
538 {
539     std::string value = String::Unbox(IString::Query(o));
540     if (!parcel.WriteInt32(VALUE_TYPE_STRING)) {
541         return false;
542     }
543     return parcel.WriteString16(Str8ToStr16(value));
544 }
545 
WriteToParcelBool(Parcel & parcel,sptr<IInterface> & o) const546 bool WantParams::WriteToParcelBool(Parcel &parcel, sptr<IInterface> &o) const
547 {
548     bool value = Boolean::Unbox(IBoolean::Query(o));
549     if (!parcel.WriteInt32(VALUE_TYPE_BOOLEAN)) {
550         return false;
551     }
552     return parcel.WriteInt8(value);
553 }
554 
WriteToParcelWantParams(Parcel & parcel,sptr<IInterface> & o,int depth) const555 bool WantParams::WriteToParcelWantParams(Parcel &parcel, sptr<IInterface> &o, int depth) const
556 {
557     WantParams value = WantParamWrapper::Unbox(IWantParams::Query(o));
558 
559     auto type = value.GetParam(TYPE_PROPERTY);
560     AAFwk::IString *typeP = AAFwk::IString::Query(type);
561     if (typeP != nullptr) {
562         std::string typeValue = AAFwk::String::Unbox(typeP);
563         if (typeValue == FD) {
564             return WriteToParcelFD(parcel, value);
565         }
566         if (typeValue == REMOTE_OBJECT) {
567             return WriteToParcelRemoteObject(parcel, value);
568         }
569     }
570 
571     if (!parcel.WriteInt32(VALUE_TYPE_WANTPARAMS)) {
572         return false;
573     }
574     return value.DoMarshalling(parcel, depth + 1);
575 }
576 
WriteToParcelFD(Parcel & parcel,const WantParams & value) const577 bool WantParams::WriteToParcelFD(Parcel &parcel, const WantParams &value) const
578 {
579     ABILITYBASE_LOGI("called");
580     if (!parcel.WriteInt32(VALUE_TYPE_FD)) {
581         return false;
582     }
583 
584     auto fdWrap = value.GetParam(VALUE_PROPERTY);
585     AAFwk::IInteger *fdIWrap = AAFwk::IInteger::Query(fdWrap);
586     if (fdIWrap != nullptr) {
587         int fd = AAFwk::Integer::Unbox(fdIWrap);
588         auto messageParcel = static_cast<MessageParcel*>(&parcel);
589         if (messageParcel == nullptr) {
590             return false;
591         }
592         bool ret = messageParcel->WriteFileDescriptor(fd);
593         ABILITYBASE_LOGI("fd:%{public}d, ret:%{public}d", fd, ret);
594         return ret;
595     }
596 
597     return false;
598 }
599 
WriteToParcelRemoteObject(Parcel & parcel,const WantParams & value) const600 bool WantParams::WriteToParcelRemoteObject(Parcel &parcel, const WantParams &value) const
601 {
602     ABILITYBASE_LOGD("called");
603     if (!parcel.WriteInt32(VALUE_TYPE_REMOTE_OBJECT)) {
604         return false;
605     }
606 
607     auto remoteObjectWrap = value.GetParam(VALUE_PROPERTY);
608     AAFwk::IRemoteObjectWrap *remoteObjectIWrap = AAFwk::IRemoteObjectWrap::Query(remoteObjectWrap);
609     if (remoteObjectIWrap != nullptr) {
610         auto remoteObject = AAFwk::RemoteObjectWrap::UnBox(remoteObjectIWrap);
611         auto messageParcel = static_cast<MessageParcel*>(&parcel);
612         if (messageParcel == nullptr) {
613             return false;
614         }
615         bool ret = messageParcel->WriteRemoteObject(remoteObject);
616         ABILITYBASE_LOGD("ret:%{public}d", ret);
617         return ret;
618     }
619     return false;
620 }
621 
WriteToParcelByte(Parcel & parcel,sptr<IInterface> & o) const622 bool WantParams::WriteToParcelByte(Parcel &parcel, sptr<IInterface> &o) const
623 {
624     byte value = Byte::Unbox(IByte::Query(o));
625     if (!parcel.WriteInt32(VALUE_TYPE_BYTE)) {
626         return false;
627     }
628     return parcel.WriteInt8(value);
629 }
630 
WriteToParcelChar(Parcel & parcel,sptr<IInterface> & o) const631 bool WantParams::WriteToParcelChar(Parcel &parcel, sptr<IInterface> &o) const
632 {
633     zchar value = Char::Unbox(IChar::Query(o));
634     if (!parcel.WriteInt32(VALUE_TYPE_CHAR)) {
635         return false;
636     }
637     return parcel.WriteInt32(value);
638 }
639 
WriteToParcelShort(Parcel & parcel,sptr<IInterface> & o) const640 bool WantParams::WriteToParcelShort(Parcel &parcel, sptr<IInterface> &o) const
641 {
642     short value = Short::Unbox(IShort::Query(o));
643     if (!parcel.WriteInt32(VALUE_TYPE_SHORT)) {
644         return false;
645     }
646     return parcel.WriteInt16(value);
647 }
648 
WriteToParcelInt(Parcel & parcel,sptr<IInterface> & o) const649 bool WantParams::WriteToParcelInt(Parcel &parcel, sptr<IInterface> &o) const
650 {
651     int value = Integer::Unbox(IInteger::Query(o));
652     if (!parcel.WriteInt32(VALUE_TYPE_INT)) {
653         return false;
654     }
655     return parcel.WriteInt32(value);
656 }
657 
WriteToParcelLong(Parcel & parcel,sptr<IInterface> & o) const658 bool WantParams::WriteToParcelLong(Parcel &parcel, sptr<IInterface> &o) const
659 {
660     long value = Long::Unbox(ILong::Query(o));
661     if (!parcel.WriteInt32(VALUE_TYPE_LONG)) {
662         return false;
663     }
664     return parcel.WriteInt64(value);
665 }
666 
WriteToParcelFloat(Parcel & parcel,sptr<IInterface> & o) const667 bool WantParams::WriteToParcelFloat(Parcel &parcel, sptr<IInterface> &o) const
668 {
669     float value = Float::Unbox(IFloat::Query(o));
670     if (!parcel.WriteInt32(VALUE_TYPE_FLOAT)) {
671         return false;
672     }
673     return parcel.WriteFloat(value);
674 }
675 
WriteToParcelDouble(Parcel & parcel,sptr<IInterface> & o) const676 bool WantParams::WriteToParcelDouble(Parcel &parcel, sptr<IInterface> &o) const
677 {
678     double value = Double::Unbox(IDouble::Query(o));
679     if (!parcel.WriteInt32(VALUE_TYPE_DOUBLE)) {
680         return false;
681     }
682     return parcel.WriteDouble(value);
683 }
684 
WriteMarshalling(Parcel & parcel,sptr<IInterface> & o,int depth) const685 bool WantParams::WriteMarshalling(Parcel &parcel, sptr<IInterface> &o, int depth) const
686 {
687     if (IString::Query(o) != nullptr) {
688         return WriteToParcelString(parcel, o);
689     } else if (IBoolean::Query(o) != nullptr) {
690         return WriteToParcelBool(parcel, o);
691     } else if (IByte::Query(o) != nullptr) {
692         return WriteToParcelByte(parcel, o);
693     } else if (IChar::Query(o) != nullptr) {
694         return WriteToParcelChar(parcel, o);
695     } else if (IShort::Query(o) != nullptr) {
696         return WriteToParcelShort(parcel, o);
697     } else if (IInteger::Query(o) != nullptr) {
698         return WriteToParcelInt(parcel, o);
699     } else if (ILong::Query(o) != nullptr) {
700         return WriteToParcelLong(parcel, o);
701     } else if (IFloat::Query(o) != nullptr) {
702         return WriteToParcelFloat(parcel, o);
703     } else if (IDouble::Query(o) != nullptr) {
704         return WriteToParcelDouble(parcel, o);
705     } else if (IWantParams::Query(o) != nullptr) {
706         return WriteToParcelWantParams(parcel, o, depth);
707     } else {
708         IArray *ao = IArray::Query(o);
709         if (ao != nullptr) {
710             sptr<IArray> array(ao);
711             return WriteArrayToParcel(parcel, array, depth);
712         } else {
713             return true;
714         }
715     }
716 }
717 
DoMarshalling(Parcel & parcel,int depth) const718 bool WantParams::DoMarshalling(Parcel &parcel, int depth) const
719 {
720     if (depth >= MAX_RECURSION_DEPTH) {
721         return false;
722     }
723     size_t size = params_.size();
724     if (!cachedUnsupportedData_.empty()) {
725         size += cachedUnsupportedData_.size();
726     }
727 
728     if (!parcel.WriteInt32(size)) {
729         return false;
730     }
731 
732     auto iter = params_.cbegin();
733     while (iter != params_.cend()) {
734         std::string key = iter->first;
735         sptr<IInterface> o = iter->second;
736         if (!parcel.WriteString16(Str8ToStr16(key))) {
737             return false;
738         }
739         if (!WriteMarshalling(parcel, o, depth)) {
740             return false;
741         }
742         iter++;
743     }
744 
745     if (!cachedUnsupportedData_.empty()) {
746         for (const UnsupportedData &data : cachedUnsupportedData_) {
747             if (!parcel.WriteString16(data.key)) {
748                 return false;
749             }
750             if (!parcel.WriteInt32(data.type)) {
751                 return false;
752             }
753             if (!parcel.WriteInt32(data.size)) {
754                 return false;
755             }
756             // Corresponding to Parcel#writeByteArray() in Java.
757             if (!parcel.WriteInt32(data.size)) {
758                 return false;
759             }
760             if (!parcel.WriteBuffer(data.buffer, data.size)) {
761                 return false;
762             }
763         }
764     }
765     return true;
766 }
767 
768 /**
769  * @description: Marshals an WantParams object into a Parcel.
770  * @param Key-value pairs in the WantParams are marshalled separately.
771  * @return If any key-value pair fails to be marshalled, false is returned.
772  */
Marshalling(Parcel & parcel) const773 bool WantParams::Marshalling(Parcel &parcel) const
774 {
775     return DoMarshalling(parcel);
776 }
777 
778 template<typename dataType, typename className>
SetArray(const InterfaceID & id,const std::vector<dataType> & value,sptr<IArray> & ao)779 static bool SetArray(const InterfaceID &id, const std::vector<dataType> &value, sptr<IArray> &ao)
780 {
781     typename std::vector<dataType>::size_type size = value.size();
782     ao = new (std::nothrow) Array(size, id);
783     if (ao != nullptr) {
784         for (typename std::vector<dataType>::size_type i = 0; i < size; i++) {
785             ao->Set(i, className::Box(value[i]));
786         }
787         return true;
788     }
789     return false;
790 }
791 
792 template<typename T1, typename T2, typename T3>
FillArray(IArray * ao,std::vector<T1> & array)793 static void FillArray(IArray *ao, std::vector<T1> &array)
794 {
795     auto func = [&](IInterface *object) {
796         if (object != nullptr) {
797             T3 *value = T3::Query(object);
798             if (value != nullptr) {
799                 array.push_back(T2::Unbox(value));
800             }
801         }
802     };
803     Array::ForEach(ao, func);
804 }
805 // inner use template function
806 template<typename T1, typename T2, typename T3>
SetNewArray(const AAFwk::InterfaceID & id,AAFwk::IArray * orgIArray,sptr<AAFwk::IArray> & ao)807 static void SetNewArray(const AAFwk::InterfaceID &id, AAFwk::IArray *orgIArray, sptr<AAFwk::IArray> &ao)
808 {
809     if (orgIArray == nullptr) {
810         return;
811     }
812     std::vector<T1> array;
813     auto func = [&](IInterface *object) {
814         if (object != nullptr) {
815             T3 *value = T3::Query(object);
816             if (value != nullptr) {
817                 array.push_back(T2::Unbox(value));
818             }
819         }
820     };
821     Array::ForEach(orgIArray, func);
822 
823     typename std::vector<T1>::size_type size = array.size();
824     if (size > 0) {
825         ao = new (std::nothrow) AAFwk::Array(size, id);
826         if (ao != nullptr) {
827             for (typename std::vector<T1>::size_type i = 0; i < size; i++) {
828                 ao->Set(i, T2::Box(array[i]));
829             }
830         }
831     }
832 }
833 
WriteArrayToParcelString(Parcel & parcel,IArray * ao) const834 bool WantParams::WriteArrayToParcelString(Parcel &parcel, IArray *ao) const
835 {
836     if (ao == nullptr) {
837         return false;
838     }
839 
840     std::vector<std::u16string> array;
841     auto func = [&](IInterface *object) {
842         std::string s = String::Unbox(IString::Query(object));
843         array.push_back(Str8ToStr16(s));
844     };
845 
846     Array::ForEach(ao, func);
847 
848     if (!parcel.WriteInt32(VALUE_TYPE_STRINGARRAY)) {
849         return false;
850     }
851     return parcel.WriteString16Vector(array);
852 }
853 
WriteArrayToParcelBool(Parcel & parcel,IArray * ao) const854 bool WantParams::WriteArrayToParcelBool(Parcel &parcel, IArray *ao) const
855 {
856     if (ao == nullptr) {
857         return false;
858     }
859 
860     std::vector<int8_t> array;
861     std::vector<int32_t> intArray;
862     FillArray<int8_t, Boolean, IBoolean>(ao, array);
863     if (!parcel.WriteInt32(VALUE_TYPE_BOOLEANARRAY)) {
864         return false;
865     }
866 
867     for (std::vector<int8_t>::size_type i = 0; i < array.size(); i++) {
868         intArray.push_back(array[i]);
869     }
870     return parcel.WriteInt32Vector(intArray);
871 }
872 
WriteArrayToParcelByte(Parcel & parcel,IArray * ao) const873 bool WantParams::WriteArrayToParcelByte(Parcel &parcel, IArray *ao) const
874 {
875     if (ao == nullptr) {
876         return false;
877     }
878 
879     std::vector<int8_t> array;
880     FillArray<int8_t, Byte, IByte>(ao, array);
881     if (!parcel.WriteInt32(VALUE_TYPE_BYTEARRAY)) {
882         return false;
883     }
884     return parcel.WriteInt8Vector(array);
885 }
886 
WriteArrayToParcelChar(Parcel & parcel,IArray * ao) const887 bool WantParams::WriteArrayToParcelChar(Parcel &parcel, IArray *ao) const
888 {
889     if (ao == nullptr) {
890         return false;
891     }
892 
893     std::vector<int32_t> array;
894     FillArray<int32_t, Char, IChar>(ao, array);
895     if (!parcel.WriteInt32(VALUE_TYPE_CHARARRAY)) {
896         return false;
897     }
898     return parcel.WriteInt32Vector(array);
899 }
900 
WriteArrayToParcelShort(Parcel & parcel,IArray * ao) const901 bool WantParams::WriteArrayToParcelShort(Parcel &parcel, IArray *ao) const
902 {
903     if (ao == nullptr) {
904         return false;
905     }
906 
907     std::vector<short> array;
908     FillArray<short, Short, IShort>(ao, array);
909     if (!parcel.WriteInt32(VALUE_TYPE_SHORTARRAY)) {
910         return false;
911     }
912     return parcel.WriteInt16Vector(array);
913 }
914 
WriteArrayToParcelInt(Parcel & parcel,IArray * ao) const915 bool WantParams::WriteArrayToParcelInt(Parcel &parcel, IArray *ao) const
916 {
917     if (ao == nullptr) {
918         return false;
919     }
920 
921     std::vector<int> array;
922     FillArray<int, Integer, IInteger>(ao, array);
923     if (!parcel.WriteInt32(VALUE_TYPE_INTARRAY)) {
924         return false;
925     }
926     return parcel.WriteInt32Vector(array);
927 }
928 
WriteArrayToParcelLong(Parcel & parcel,IArray * ao) const929 bool WantParams::WriteArrayToParcelLong(Parcel &parcel, IArray *ao) const
930 {
931     if (ao == nullptr) {
932         return false;
933     }
934 
935     std::vector<int64_t> array;
936     FillArray<int64_t, Long, ILong>(ao, array);
937     if (!parcel.WriteInt32(VALUE_TYPE_LONGARRAY)) {
938         return false;
939     }
940     return parcel.WriteInt64Vector(array);
941 }
942 
WriteArrayToParcelFloat(Parcel & parcel,IArray * ao) const943 bool WantParams::WriteArrayToParcelFloat(Parcel &parcel, IArray *ao) const
944 {
945     if (ao == nullptr) {
946         return false;
947     }
948 
949     std::vector<float> array;
950     FillArray<float, Float, IFloat>(ao, array);
951     if (!parcel.WriteInt32(VALUE_TYPE_FLOATARRAY)) {
952         return false;
953     }
954     return parcel.WriteFloatVector(array);
955 }
956 
WriteArrayToParcelDouble(Parcel & parcel,IArray * ao) const957 bool WantParams::WriteArrayToParcelDouble(Parcel &parcel, IArray *ao) const
958 {
959     if (ao == nullptr) {
960         return false;
961     }
962 
963     std::vector<double> array;
964     FillArray<double, Double, IDouble>(ao, array);
965     if (!parcel.WriteInt32(VALUE_TYPE_DOUBLEARRAY)) {
966         return false;
967     }
968     return parcel.WriteDoubleVector(array);
969 }
970 
WriteArrayToParcelWantParams(Parcel & parcel,IArray * ao,int depth) const971 bool WantParams::WriteArrayToParcelWantParams(Parcel &parcel, IArray *ao, int depth) const
972 {
973     if (ao == nullptr) {
974         return false;
975     }
976     if (!parcel.WriteInt32(VALUE_TYPE_WANTPARAMSARRAY)) {
977         return false;
978     }
979     std::vector<WantParams> array;
980     auto func = [&](AAFwk::IInterface *object) {
981         if (object != nullptr) {
982             IWantParams *value = AAFwk::IWantParams::Query(object);
983             if (value != nullptr) {
984                 array.push_back(AAFwk::WantParamWrapper::Unbox(value));
985             }
986         }
987     };
988     AAFwk::Array::ForEach(ao, func);
989     if (!parcel.WriteInt32(array.size())) {
990         return false;
991     }
992 
993     for (const auto& wp : array) {
994         if (!wp.DoMarshalling(parcel, depth + 1)) {
995             return false;
996         }
997     }
998     return true;
999 }
1000 
WriteArrayToParcel(Parcel & parcel,IArray * ao,int depth) const1001 bool WantParams::WriteArrayToParcel(Parcel &parcel, IArray *ao, int depth) const
1002 {
1003     if (Array::IsStringArray(ao)) {
1004         return WriteArrayToParcelString(parcel, ao);
1005     } else if (Array::IsBooleanArray(ao)) {
1006         return WriteArrayToParcelBool(parcel, ao);
1007     } else if (Array::IsByteArray(ao)) {
1008         return WriteArrayToParcelByte(parcel, ao);
1009     } else if (Array::IsCharArray(ao)) {
1010         return WriteArrayToParcelChar(parcel, ao);
1011     } else if (Array::IsShortArray(ao)) {
1012         return WriteArrayToParcelShort(parcel, ao);
1013     } else if (Array::IsIntegerArray(ao)) {
1014         return WriteArrayToParcelInt(parcel, ao);
1015     } else if (Array::IsLongArray(ao)) {
1016         return WriteArrayToParcelLong(parcel, ao);
1017     } else if (Array::IsFloatArray(ao)) {
1018         return WriteArrayToParcelFloat(parcel, ao);
1019     } else if (Array::IsDoubleArray(ao)) {
1020         return WriteArrayToParcelDouble(parcel, ao);
1021     } else if (Array::IsWantParamsArray(ao)) {
1022         return WriteArrayToParcelWantParams(parcel, ao, depth);
1023     } else {
1024         return true;
1025     }
1026 }
1027 
ReadFromParcelArrayString(Parcel & parcel,sptr<IArray> & ao)1028 bool WantParams::ReadFromParcelArrayString(Parcel &parcel, sptr<IArray> &ao)
1029 {
1030     std::vector<std::u16string> value;
1031     if (!parcel.ReadString16Vector(&value)) {
1032         ABILITYBASE_LOGE("read string of array fail");
1033         return false;
1034     }
1035 
1036     std::vector<std::u16string>::size_type size = value.size();
1037     ao = new (std::nothrow) Array(size, g_IID_IString);
1038     if (ao != nullptr) {
1039         for (std::vector<std::u16string>::size_type i = 0; i < size; i++) {
1040             ao->Set(i, String::Box(Str16ToStr8(value[i])));
1041         }
1042         return true;
1043     } else {
1044         ABILITYBASE_LOGE("null ao");
1045     }
1046     return false;
1047 }
1048 
ReadFromParcelArrayBool(Parcel & parcel,sptr<IArray> & ao)1049 bool WantParams::ReadFromParcelArrayBool(Parcel &parcel, sptr<IArray> &ao)
1050 {
1051     std::vector<int32_t> value;
1052     std::vector<int8_t> boolValue;
1053     if (!parcel.ReadInt32Vector(&value)) {
1054         ABILITYBASE_LOGE("read bool of array fail");
1055         return false;
1056     }
1057 
1058     std::vector<int32_t>::size_type size = value.size();
1059     for (std::vector<int32_t>::size_type i = 0; i < size; i++) {
1060         boolValue.push_back(value[i]);
1061     }
1062     return SetArray<int8_t, Boolean>(g_IID_IBoolean, boolValue, ao);
1063 }
1064 
ReadFromParcelArrayByte(Parcel & parcel,sptr<IArray> & ao)1065 bool WantParams::ReadFromParcelArrayByte(Parcel &parcel, sptr<IArray> &ao)
1066 {
1067     std::vector<int8_t> value;
1068     if (!parcel.ReadInt8Vector(&value)) {
1069         ABILITYBASE_LOGE("read value failed");
1070         return false;
1071     }
1072     return SetArray<int8_t, Byte>(g_IID_IByte, value, ao);
1073 }
1074 
ReadFromParcelArrayChar(Parcel & parcel,sptr<IArray> & ao)1075 bool WantParams::ReadFromParcelArrayChar(Parcel &parcel, sptr<IArray> &ao)
1076 {
1077     std::vector<int32_t> value;
1078     if (!parcel.ReadInt32Vector(&value)) {
1079         ABILITYBASE_LOGE("read value failed");
1080         return false;
1081     }
1082     return SetArray<int32_t, Char>(g_IID_IChar, value, ao);
1083 }
1084 
ReadFromParcelArrayShort(Parcel & parcel,sptr<IArray> & ao)1085 bool WantParams::ReadFromParcelArrayShort(Parcel &parcel, sptr<IArray> &ao)
1086 {
1087     std::vector<short> value;
1088     if (!parcel.ReadInt16Vector(&value)) {
1089         ABILITYBASE_LOGE("read value failed");
1090         return false;
1091     }
1092     return SetArray<short, Short>(g_IID_IShort, value, ao);
1093 }
1094 
ReadFromParcelArrayInt(Parcel & parcel,sptr<IArray> & ao)1095 bool WantParams::ReadFromParcelArrayInt(Parcel &parcel, sptr<IArray> &ao)
1096 {
1097     std::vector<int> value;
1098     if (!parcel.ReadInt32Vector(&value)) {
1099         ABILITYBASE_LOGE("read value failed");
1100         return false;
1101     }
1102     return SetArray<int, Integer>(g_IID_IInteger, value, ao);
1103 }
1104 
ReadFromParcelArrayLong(Parcel & parcel,sptr<IArray> & ao)1105 bool WantParams::ReadFromParcelArrayLong(Parcel &parcel, sptr<IArray> &ao)
1106 {
1107     std::vector<int64_t> value;
1108     if (!parcel.ReadInt64Vector(&value)) {
1109         ABILITYBASE_LOGE("read value failed");
1110         return false;
1111     }
1112 
1113 #ifdef WANT_PARAM_USE_LONG
1114     return SetArray<int64_t, Long>(g_IID_ILong, value, ao);
1115 #else
1116     std::vector<std::string> strList;
1117     for (size_t i = 0; i < value.size(); i++) {
1118         strList.push_back(std::to_string(value[i]));
1119     }
1120     return SetArray<std::string, String>(g_IID_IString, strList, ao);
1121 #endif
1122 }
1123 
ReadFromParcelArrayFloat(Parcel & parcel,sptr<IArray> & ao)1124 bool WantParams::ReadFromParcelArrayFloat(Parcel &parcel, sptr<IArray> &ao)
1125 {
1126     std::vector<float> value;
1127     if (!parcel.ReadFloatVector(&value)) {
1128         ABILITYBASE_LOGE("read value failed");
1129         return false;
1130     }
1131     return SetArray<float, Float>(g_IID_IFloat, value, ao);
1132 }
1133 
ReadFromParcelArrayDouble(Parcel & parcel,sptr<IArray> & ao)1134 bool WantParams::ReadFromParcelArrayDouble(Parcel &parcel, sptr<IArray> &ao)
1135 {
1136     std::vector<double> value;
1137     if (!parcel.ReadDoubleVector(&value)) {
1138         ABILITYBASE_LOGE("read value failed");
1139         return false;
1140     }
1141     return SetArray<double, Double>(g_IID_IDouble, value, ao);
1142 }
1143 
ReadFromParcelArrayWantParams(Parcel & parcel,sptr<IArray> & ao,int depth)1144 bool WantParams::ReadFromParcelArrayWantParams(Parcel &parcel, sptr<IArray> &ao, int depth)
1145 {
1146     int32_t size = parcel.ReadInt32();
1147     static constexpr int32_t maxAllowedSize = 1024;
1148     if (size < 0 || size > maxAllowedSize) {
1149         ABILITYBASE_LOGE("invalid size: %{public}d", size);
1150         return false;
1151     }
1152     std::vector<sptr<IInterface>> arrayWantParams;
1153     for (int32_t i = 0; i < size; ++i) {
1154         sptr<WantParams> value(Unmarshalling(parcel, depth + 1));
1155         if (value != nullptr) {
1156             sptr<IInterface> interface = WantParamWrapper::Box(*value);
1157             if (interface != nullptr) {
1158                 arrayWantParams.push_back(interface);
1159             }
1160         }
1161     }
1162 
1163     ao = new (std::nothrow) AAFwk::Array(arrayWantParams.size(), AAFwk::g_IID_IWantParams);
1164     if (ao != nullptr) {
1165         for (size_t i = 0; i < arrayWantParams.size(); i++) {
1166             ao->Set(i, arrayWantParams[i]);
1167         }
1168         return true;
1169     }
1170     return false;
1171 }
1172 
ReadArrayToParcel(Parcel & parcel,int type,sptr<IArray> & ao,int depth)1173 bool WantParams::ReadArrayToParcel(Parcel &parcel, int type, sptr<IArray> &ao, int depth)
1174 {
1175     switch (type) {
1176         case VALUE_TYPE_STRINGARRAY:
1177         case VALUE_TYPE_CHARSEQUENCEARRAY:
1178             return ReadFromParcelArrayString(parcel, ao);
1179         case VALUE_TYPE_BOOLEANARRAY:
1180             return ReadFromParcelArrayBool(parcel, ao);
1181         case VALUE_TYPE_BYTEARRAY:
1182             return ReadFromParcelArrayByte(parcel, ao);
1183         case VALUE_TYPE_CHARARRAY:
1184             return ReadFromParcelArrayChar(parcel, ao);
1185         case VALUE_TYPE_SHORTARRAY:
1186             return ReadFromParcelArrayShort(parcel, ao);
1187         case VALUE_TYPE_INTARRAY:
1188             return ReadFromParcelArrayInt(parcel, ao);
1189         case VALUE_TYPE_LONGARRAY:
1190             return ReadFromParcelArrayLong(parcel, ao);
1191         case VALUE_TYPE_FLOATARRAY:
1192             return ReadFromParcelArrayFloat(parcel, ao);
1193         case VALUE_TYPE_DOUBLEARRAY:
1194             return ReadFromParcelArrayDouble(parcel, ao);
1195         case VALUE_TYPE_WANTPARAMSARRAY:
1196             return ReadFromParcelArrayWantParams(parcel, ao, depth);
1197         default:
1198             break;
1199     }
1200 
1201     return true;
1202 }
1203 
ReadFromParcelString(Parcel & parcel,const std::string & key)1204 bool WantParams::ReadFromParcelString(Parcel &parcel, const std::string &key)
1205 {
1206     std::u16string value = parcel.ReadString16();
1207     std::string strValue(Str16ToStr8(value));
1208     sptr<IInterface> intf = String::Box(Str16ToStr8(value));
1209     if (intf) {
1210         SetParam(key, intf);
1211     } else {
1212         ABILITYBASE_LOGE("read data fail: key=%{public}s", key.c_str());
1213     }
1214     return true;
1215 }
1216 
ReadFromParcelBool(Parcel & parcel,const std::string & key)1217 bool WantParams::ReadFromParcelBool(Parcel &parcel, const std::string &key)
1218 {
1219     int8_t value;
1220     if (parcel.ReadInt8(value)) {
1221         sptr<IInterface> intf = Boolean::Box(value);
1222         if (intf) {
1223             SetParam(key, intf);
1224         } else {
1225             ABILITYBASE_LOGE("insert param fail: key=%{public}s", key.c_str());
1226         }
1227         return true;
1228     } else {
1229         ABILITYBASE_LOGE("read data fail: key=%{public}s", key.c_str());
1230         return false;
1231     }
1232 }
1233 
ReadFromParcelInt8(Parcel & parcel,const std::string & key)1234 bool WantParams::ReadFromParcelInt8(Parcel &parcel, const std::string &key)
1235 {
1236     int8_t value;
1237     if (parcel.ReadInt8(value)) {
1238         sptr<IInterface> intf = Byte::Box(value);
1239         if (intf) {
1240             SetParam(key, intf);
1241         } else {
1242             ABILITYBASE_LOGE("insert arguments fail: key=%{public}s", key.c_str());
1243         }
1244         return true;
1245     } else {
1246         ABILITYBASE_LOGE("read data error: key=%{public}s", key.c_str());
1247         return false;
1248     }
1249 }
1250 
ReadFromParcelChar(Parcel & parcel,const std::string & key)1251 bool WantParams::ReadFromParcelChar(Parcel &parcel, const std::string &key)
1252 {
1253     int32_t value;
1254     if (parcel.ReadInt32(value)) {
1255         sptr<IInterface> intf = Char::Box(value);
1256         if (intf) {
1257             SetParam(key, intf);
1258         } else {
1259             ABILITYBASE_LOGE("insert param error: key=%{public}s", key.c_str());
1260         }
1261         return true;
1262     } else {
1263         ABILITYBASE_LOGE("read data error: key=%{public}s", key.c_str());
1264         return false;
1265     }
1266 }
1267 
ReadFromParcelShort(Parcel & parcel,const std::string & key)1268 bool WantParams::ReadFromParcelShort(Parcel &parcel, const std::string &key)
1269 {
1270     short value;
1271     if (parcel.ReadInt16(value)) {
1272         sptr<IInterface> intf = Short::Box(value);
1273         if (intf) {
1274             SetParam(key, intf);
1275         } else {
1276             ABILITYBASE_LOGE("insert arguments error: key=%{public}s", key.c_str());
1277         }
1278         return true;
1279     } else {
1280         ABILITYBASE_LOGE("read data fail: key=%{public}s", key.c_str());
1281         return false;
1282     }
1283 }
1284 
ReadFromParcelInt(Parcel & parcel,const std::string & key)1285 bool WantParams::ReadFromParcelInt(Parcel &parcel, const std::string &key)
1286 {
1287     int value;
1288     if (parcel.ReadInt32(value)) {
1289         sptr<IInterface> intf = Integer::Box(value);
1290         if (intf) {
1291             SetParam(key, intf);
1292         } else {
1293             ABILITYBASE_LOGE("insert param fail: key:%{public}s", key.c_str());
1294         }
1295         return true;
1296     } else {
1297         ABILITYBASE_LOGE("read data fail: key:%{public}s", key.c_str());
1298         return false;
1299     }
1300 }
1301 
ReadFromParcelWantParamWrapper(Parcel & parcel,const std::string & key,int type,int depth)1302 bool WantParams::ReadFromParcelWantParamWrapper(Parcel &parcel, const std::string &key, int type, int depth)
1303 {
1304     if (type == VALUE_TYPE_FD) {
1305         return ReadFromParcelFD(parcel, key);
1306     }
1307 
1308     if (type == VALUE_TYPE_INVALID_FD) {
1309         ABILITYBASE_LOGE("fd invalid");
1310         return true;
1311     }
1312 
1313     if (type == VALUE_TYPE_REMOTE_OBJECT) {
1314         return ReadFromParcelRemoteObject(parcel, key);
1315     }
1316 
1317     sptr<WantParams> value(Unmarshalling(parcel, depth + 1));
1318     if (value != nullptr) {
1319         sptr<IInterface> intf = WantParamWrapper::Box(*value);
1320         if (intf) {
1321             SetParam(key, intf);
1322         }
1323     }
1324 
1325     return true;
1326 }
1327 
ReadFromParcelFD(Parcel & parcel,const std::string & key)1328 bool WantParams::ReadFromParcelFD(Parcel &parcel, const std::string &key)
1329 {
1330     auto messageParcel = static_cast<MessageParcel*>(&parcel);
1331     if (messageParcel == nullptr) {
1332         return false;
1333     }
1334     auto fd = messageParcel->ReadFileDescriptor();
1335     ABILITYBASE_LOGI("fd:%{public}d", fd);
1336     WantParams wp;
1337     wp.SetParam(TYPE_PROPERTY, String::Box(FD));
1338     wp.SetParam(VALUE_PROPERTY, Integer::Box(fd));
1339     sptr<AAFwk::IWantParams> pWantParams = AAFwk::WantParamWrapper::Box(wp);
1340     SetParam(key, pWantParams);
1341     fds_[key] = fd;
1342     return true;
1343 }
1344 
ReadFromParcelRemoteObject(Parcel & parcel,const std::string & key)1345 bool WantParams::ReadFromParcelRemoteObject(Parcel &parcel, const std::string &key)
1346 {
1347     ABILITYBASE_LOGD("called");
1348     auto messageParcel = static_cast<MessageParcel*>(&parcel);
1349     if (messageParcel == nullptr) {
1350         return false;
1351     }
1352     auto remoteObject = messageParcel->ReadRemoteObject();
1353     WantParams wp;
1354     wp.SetParam(TYPE_PROPERTY, String::Box(REMOTE_OBJECT));
1355     wp.SetParam(VALUE_PROPERTY, RemoteObjectWrap::Box(remoteObject));
1356     sptr<AAFwk::IWantParams> pWantParams = AAFwk::WantParamWrapper::Box(wp);
1357     SetParam(key, pWantParams);
1358     return true;
1359 }
1360 
ReadFromParcelLong(Parcel & parcel,const std::string & key)1361 bool WantParams::ReadFromParcelLong(Parcel &parcel, const std::string &key)
1362 {
1363     int64_t value;
1364     if (parcel.ReadInt64(value)) {
1365         std::string strValue(std::to_string(value));
1366 #ifdef WANT_PARAM_USE_LONG
1367         sptr<IInterface> intf = Long::Box(value);
1368 #else
1369         sptr<IInterface> intf = String::Box(std::to_string(value));
1370 #endif
1371         if (intf) {
1372             SetParam(key, intf);
1373         } else {
1374             ABILITYBASE_LOGE("insert param fail: key=%{public}s", key.c_str());
1375         }
1376         return true;
1377     } else {
1378         ABILITYBASE_LOGE("read data error: key:%{public}s", key.c_str());
1379         return false;
1380     }
1381 }
1382 
ReadFromParcelFloat(Parcel & parcel,const std::string & key)1383 bool WantParams::ReadFromParcelFloat(Parcel &parcel, const std::string &key)
1384 {
1385     float value;
1386     if (parcel.ReadFloat(value)) {
1387         sptr<IInterface> intf = Float::Box(value);
1388         if (intf) {
1389             SetParam(key, intf);
1390         } else {
1391             ABILITYBASE_LOGE("insert parameter fail: key=%{public}s", key.c_str());
1392         }
1393         return true;
1394     } else {
1395         ABILITYBASE_LOGE("read data fail: key=%{public}s", key.c_str());
1396         return false;
1397     }
1398 }
1399 
ReadFromParcelDouble(Parcel & parcel,const std::string & key)1400 bool WantParams::ReadFromParcelDouble(Parcel &parcel, const std::string &key)
1401 {
1402     double value;
1403     if (parcel.ReadDouble(value)) {
1404         sptr<IInterface> intf = Double::Box(value);
1405         if (intf) {
1406             SetParam(key, intf);
1407         } else {
1408             ABILITYBASE_LOGE("insert parameter fail: key:%{public}s", key.c_str());
1409         }
1410         return true;
1411     } else {
1412         ABILITYBASE_LOGE("read data fail: key=%{public}s", key.c_str());
1413         return false;
1414     }
1415 }
1416 
ReadUnsupportedData(Parcel & parcel,const std::string & key,int type)1417 bool WantParams::ReadUnsupportedData(Parcel &parcel, const std::string &key, int type)
1418 {
1419     int32_t bufferSize = 0;
1420     if (!parcel.ReadInt32(bufferSize)) {
1421         return false;
1422     }
1423     static constexpr int32_t maxAllowedSize = 100 * 1024 * 1024;
1424     if (bufferSize < 0 || bufferSize > maxAllowedSize) {
1425         ABILITYBASE_LOGE("invalid size: %{public}d", bufferSize);
1426         return false;
1427     }
1428 
1429     // Corresponding to Parcel#writeByteArray() in Java.
1430     int32_t length = 0;
1431     if (!parcel.ReadInt32(length)) {
1432         return false;
1433     }
1434     const uint8_t *bufferP = parcel.ReadUnpadBuffer(bufferSize);
1435     if (bufferP == nullptr) {
1436         return false;
1437     }
1438 
1439     UnsupportedData data;
1440     data.key = Str8ToStr16(key);
1441     data.type = type;
1442     data.size = bufferSize;
1443     data.buffer = new (std::nothrow) uint8_t[bufferSize];
1444     if (data.buffer == nullptr) {
1445         return false;
1446     }
1447 
1448     if (memcpy_s(data.buffer, bufferSize, bufferP, bufferSize) != EOK) {
1449         return false;
1450     }
1451     cachedUnsupportedData_.emplace_back(std::move(data));
1452     return true;
1453 }
1454 
ReadFromParcelParam(Parcel & parcel,const std::string & key,int type,int depth)1455 bool WantParams::ReadFromParcelParam(Parcel &parcel, const std::string &key, int type, int depth)
1456 {
1457     if (depth >= MAX_RECURSION_DEPTH) {
1458         return false;
1459     }
1460     switch (type) {
1461         case VALUE_TYPE_CHARSEQUENCE:
1462         case VALUE_TYPE_STRING:
1463             return ReadFromParcelString(parcel, key);
1464         case VALUE_TYPE_BOOLEAN:
1465             return ReadFromParcelBool(parcel, key);
1466         case VALUE_TYPE_BYTE:
1467             return ReadFromParcelInt8(parcel, key);
1468         case VALUE_TYPE_CHAR:
1469             return ReadFromParcelChar(parcel, key);
1470         case VALUE_TYPE_SHORT:
1471             return ReadFromParcelShort(parcel, key);
1472         case VALUE_TYPE_INT:
1473             return ReadFromParcelInt(parcel, key);
1474         case VALUE_TYPE_LONG:
1475             return ReadFromParcelLong(parcel, key);
1476         case VALUE_TYPE_FLOAT:
1477             return ReadFromParcelFloat(parcel, key);
1478         case VALUE_TYPE_DOUBLE:
1479             return ReadFromParcelDouble(parcel, key);
1480         case VALUE_TYPE_WANTPARAMS:
1481         case VALUE_TYPE_FD:
1482         case VALUE_TYPE_REMOTE_OBJECT:
1483             return ReadFromParcelWantParamWrapper(parcel, key, type, depth);
1484         case VALUE_TYPE_NULL:
1485             break;
1486         case VALUE_TYPE_PARCELABLE:
1487         case VALUE_TYPE_PARCELABLEARRAY:
1488         case VALUE_TYPE_SERIALIZABLE:
1489         case VALUE_TYPE_LIST:
1490             if (!ReadUnsupportedData(parcel, key, type)) {
1491                 return false;
1492             }
1493             break;
1494         default: {
1495             // handle array
1496             sptr<IArray> ao = nullptr;
1497             if (!ReadArrayToParcel(parcel, type, ao, depth)) {
1498                 return false;
1499             }
1500             sptr<IInterface> intf = ao;
1501             if (intf) {
1502                 SetParam(key, intf);
1503             }
1504             break;
1505         }
1506     }
1507     return true;
1508 }
1509 
ReadFromParcel(Parcel & parcel,int depth)1510 bool WantParams::ReadFromParcel(Parcel &parcel, int depth)
1511 {
1512     int32_t size;
1513     if (!parcel.ReadInt32(size)) {
1514         ABILITYBASE_LOGE("read size fail");
1515         return false;
1516     }
1517     for (int32_t i = 0; i < size; i++) {
1518         std::u16string key = parcel.ReadString16();
1519         int type;
1520         if (!parcel.ReadInt32(type)) {
1521             ABILITYBASE_LOGE("read type fail");
1522             return false;
1523         }
1524         if (!ReadFromParcelParam(parcel, Str16ToStr8(key), type, depth)) {
1525             ABILITYBASE_LOGE("get i=%{public}d fail", i);
1526             return false;
1527         }
1528     }
1529     return true;
1530 }
1531 
1532 /**
1533  * @description: Unmarshals an WantParams object from a Parcel.
1534  * @param Key-value pairs in the WantParams are unmarshalled separately.
1535  * @return If any key-value pair fails to be unmarshalled, false is returned.
1536  */
Unmarshalling(Parcel & parcel,int depth)1537 WantParams *WantParams::Unmarshalling(Parcel &parcel, int depth)
1538 {
1539     WantParams *wantParams = new (std::nothrow) WantParams();
1540     if (wantParams == nullptr) {
1541         return nullptr;
1542     }
1543     if (!wantParams->ReadFromParcel(parcel, depth)) {
1544         delete wantParams;
1545         wantParams = nullptr;
1546     }
1547     return wantParams;
1548 }
1549 
DumpInfo(int level) const1550 void WantParams::DumpInfo(int level) const
1551 {
1552     for (auto it : params_) {
1553         int typeId = WantParams::GetDataType(it.second);
1554         if (typeId != VALUE_TYPE_NULL) {
1555             std::string value = WantParams::GetStringByType(it.second, typeId);
1556             ABILITYBASE_LOGI("=WantParams[%{public}s]:%{private}s =======", it.first.c_str(), value.c_str());
1557         } else {
1558             ABILITYBASE_LOGE("=WantParams[%{public}s]:type error =======", it.first.c_str());
1559         }
1560     }
1561 }
1562 
CloseAllFd()1563 void WantParams::CloseAllFd()
1564 {
1565     for (auto it : fds_) {
1566         if (it.second > 0) {
1567             ABILITYBASE_LOGI("fd:%{public}d", it.second);
1568             close(it.second);
1569         }
1570         params_.erase(it.first);
1571     }
1572     fds_.clear();
1573 }
1574 
RemoveAllFd()1575 void WantParams::RemoveAllFd()
1576 {
1577     for (auto it : fds_) {
1578         params_.erase(it.first);
1579     }
1580     fds_.clear();
1581 }
1582 
DupAllFd()1583 void WantParams::DupAllFd()
1584 {
1585     for (auto it : fds_) {
1586         if (it.second > 0) {
1587             int dupFd = dup(it.second);
1588             if (dupFd > 0) {
1589                 params_.erase(it.first);
1590                 WantParams wp;
1591                 wp.SetParam(TYPE_PROPERTY, String::Box(FD));
1592                 wp.SetParam(VALUE_PROPERTY, Integer::Box(dupFd));
1593                 sptr<AAFwk::IWantParams> pWantParams = AAFwk::WantParamWrapper::Box(wp);
1594                 SetParam(it.first, pWantParams);
1595                 fds_[it.first] = dupFd;
1596             }
1597         }
1598     }
1599 }
1600 
GetCachedUnsupportedData(std::vector<UnsupportedData> & cachedUnsupportedData) const1601 void WantParams::GetCachedUnsupportedData(std::vector<UnsupportedData> &cachedUnsupportedData) const
1602 {
1603     for (UnsupportedData item : cachedUnsupportedData_) {
1604         cachedUnsupportedData.emplace_back(std::move(item));
1605     }
1606 }
1607 
SetCachedUnsupportedData(const std::vector<UnsupportedData> & cachedUnsupportedData)1608 void WantParams::SetCachedUnsupportedData(const std::vector<UnsupportedData> &cachedUnsupportedData)
1609 {
1610     cachedUnsupportedData_ = cachedUnsupportedData;
1611 }
1612 }  // namespace AAFwk
1613 }  // namespace OHOS
1614