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