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