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