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