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