1 /*
2 * Copyright (c) 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 "bundle_manager_adapter_proxy.h"
17 #include "ability_info.h"
18 #include "account_error_no.h"
19 #include "account_log_wrapper.h"
20 #include "nlohmann/json.hpp"
21 #include "securec.h"
22 #include "string_ex.h"
23
24 namespace OHOS {
25 namespace AccountSA {
26 namespace {
27 const int32_t ASHMEM_LEN = 16;
28 const int32_t MAX_INFO_SIZE = 1048576; // 1024 x 1024
29 const char BUNDLE_INFO_NAME[] = "name";
30 const char BUNDLE_INFO_LABEL[] = "label";
31 const char BUNDLE_INFO_DESCRIPTION[] = "description";
32 const char BUNDLE_INFO_SINGLETON[] = "singleton";
33 const char BUNDLE_INFO_IS_NATIVE_APP[] = "isNativeApp";
34 const char BUNDLE_INFO_APPID[] = "appId";
35 const char BUNDLE_INFO_APP_INDEX[] = "appIndex";
36 const char BUNDLE_INFO_EXTENSION_ABILITY_INFOS[] = "extensionAbilityInfo";
37 const char EXTENSION_NAME[] = "name";
38 const char EXTENSION_LABEL[] = "label";
39 const char EXTENSION_DESCRIPTION[] = "description";
40 const char EXTENSION_TYPE[] = "type";
41 const char EXTENSION_VISIBLE[] = "visible";
42 const char EXTENSION_UID[] = "uid";
43 }
44
ClearAshmem(sptr<Ashmem> & optMem)45 inline void ClearAshmem(sptr<Ashmem> &optMem)
46 {
47 if (optMem != nullptr) {
48 optMem->UnmapAshmem();
49 optMem->CloseAshmem();
50 }
51 }
52
ParseExtensionInfo(std::string infoStr,ExtensionAbilityInfo & extensionInfo)53 bool BundleManagerAdapterProxy::ParseExtensionInfo(std::string infoStr, ExtensionAbilityInfo &extensionInfo)
54 {
55 nlohmann::json jsonObject = nlohmann::json::parse(infoStr.c_str(), nullptr, false);
56 if (jsonObject.is_discarded()) {
57 ACCOUNT_LOGE("failed due to data is discarded");
58 return false;
59 }
60 if ((jsonObject.find(EXTENSION_NAME) != jsonObject.end()) && jsonObject.at(EXTENSION_NAME).is_string()) {
61 extensionInfo.name = jsonObject.at(EXTENSION_NAME).get<std::string>();
62 }
63 if ((jsonObject.find(EXTENSION_LABEL) != jsonObject.end()) && jsonObject.at(EXTENSION_LABEL).is_string()) {
64 extensionInfo.label = jsonObject.at(EXTENSION_LABEL).get<std::string>();
65 }
66 if ((jsonObject.find(EXTENSION_DESCRIPTION) != jsonObject.end()) &&
67 jsonObject.at(EXTENSION_DESCRIPTION).is_string()) {
68 extensionInfo.description = jsonObject.at(EXTENSION_DESCRIPTION).get<std::string>();
69 }
70 if ((jsonObject.find(EXTENSION_TYPE) != jsonObject.end()) &&
71 jsonObject.at(EXTENSION_TYPE).is_number()) {
72 extensionInfo.type = static_cast<ExtensionAbilityType>(jsonObject.at(EXTENSION_TYPE).get<int32_t>());
73 }
74 if ((jsonObject.find(EXTENSION_VISIBLE) != jsonObject.end()) &&
75 jsonObject.at(EXTENSION_VISIBLE).is_boolean()) {
76 extensionInfo.visible = jsonObject.at(EXTENSION_VISIBLE).get<bool>();
77 }
78 if ((jsonObject.find(EXTENSION_UID) != jsonObject.end()) &&
79 jsonObject.at(EXTENSION_UID).is_number()) {
80 extensionInfo.uid = jsonObject.at(EXTENSION_UID).get<int32_t>();
81 }
82 return true;
83 }
84
BundleManagerAdapterProxy(const sptr<IRemoteObject> & impl)85 BundleManagerAdapterProxy::BundleManagerAdapterProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IBundleMgr>(impl)
86 {}
87
~BundleManagerAdapterProxy()88 BundleManagerAdapterProxy::~BundleManagerAdapterProxy()
89 {}
90
ParseStr(const char * buf,const int itemLen,int index,std::string & result)91 bool BundleManagerAdapterProxy::ParseStr(const char *buf, const int itemLen, int index, std::string &result)
92 {
93 ACCOUNT_LOGD("ParseStr itemLen:%{public}d index:%{public}d.", itemLen, index);
94 if (buf == nullptr || itemLen <= 0 || index < 0) {
95 ACCOUNT_LOGE("param invalid.");
96 return false;
97 }
98
99 char item[itemLen + 1];
100 if (strncpy_s(item, sizeof(item), buf + index, itemLen) != 0) {
101 ACCOUNT_LOGE("ParseStr failed due to strncpy_s error.");
102 return false;
103 }
104
105 std::string str(item, 0, itemLen);
106 result = str;
107 return true;
108 }
109
ParseExtensionAbilityInfos(nlohmann::json jsonObject,std::vector<ExtensionAbilityInfo> & extensionInfos)110 bool BundleManagerAdapterProxy::ParseExtensionAbilityInfos(
111 nlohmann::json jsonObject, std::vector<ExtensionAbilityInfo> &extensionInfos)
112 {
113 if ((jsonObject.find(BUNDLE_INFO_EXTENSION_ABILITY_INFOS) == jsonObject.end()) ||
114 (!jsonObject.at(BUNDLE_INFO_EXTENSION_ABILITY_INFOS).is_array())) {
115 return true;
116 }
117 auto arrays = jsonObject.at(BUNDLE_INFO_EXTENSION_ABILITY_INFOS);
118 if (arrays.empty()) {
119 return true;
120 }
121 if (arrays.size() > Constants::MAX_JSON_ARRAY_LENGTH) {
122 ACCOUNT_LOGE("array is oversize");
123 return false;
124 }
125 for (const auto &iter : arrays) {
126 if (!iter.is_object()) {
127 ACCOUNT_LOGE("array %{public}s exist error type info", BUNDLE_INFO_EXTENSION_ABILITY_INFOS);
128 continue;
129 }
130 ExtensionAbilityInfo abilityInfo;
131 if (!ParseExtensionInfo(iter.dump(), abilityInfo)) {
132 continue;
133 }
134 extensionInfos.emplace_back(abilityInfo);
135 }
136 return true;
137 }
138
139 template<typename T>
ParseInfo(std::string & infoStr,T & info)140 bool BundleManagerAdapterProxy::ParseInfo(std::string &infoStr, T &info)
141 {
142 nlohmann::json jsonObject = nlohmann::json::parse(infoStr.c_str(), nullptr, false);
143 if (jsonObject.is_discarded()) {
144 ACCOUNT_LOGE("failed due to data is discarded");
145 return false;
146 }
147
148 if ((jsonObject.find(BUNDLE_INFO_NAME) != jsonObject.end()) && jsonObject.at(BUNDLE_INFO_NAME).is_string()) {
149 info.name = jsonObject.at(BUNDLE_INFO_NAME).get<std::string>();
150 }
151 if ((jsonObject.find(BUNDLE_INFO_LABEL) != jsonObject.end()) && jsonObject.at(BUNDLE_INFO_LABEL).is_string()) {
152 info.label = jsonObject.at(BUNDLE_INFO_LABEL).get<std::string>();
153 }
154 if ((jsonObject.find(BUNDLE_INFO_DESCRIPTION) != jsonObject.end()) &&
155 jsonObject.at(BUNDLE_INFO_DESCRIPTION).is_string()) {
156 info.description = jsonObject.at(BUNDLE_INFO_DESCRIPTION).get<std::string>();
157 }
158 if ((jsonObject.find(BUNDLE_INFO_SINGLETON) != jsonObject.end()) &&
159 jsonObject.at(BUNDLE_INFO_SINGLETON).is_boolean()) {
160 info.singleton = jsonObject.at(BUNDLE_INFO_SINGLETON).get<bool>();
161 }
162 if ((jsonObject.find(BUNDLE_INFO_IS_NATIVE_APP) != jsonObject.end()) &&
163 jsonObject.at(BUNDLE_INFO_IS_NATIVE_APP).is_boolean()) {
164 info.isNativeApp = jsonObject.at(BUNDLE_INFO_IS_NATIVE_APP).get<bool>();
165 }
166 if ((jsonObject.find(BUNDLE_INFO_APPID) != jsonObject.end()) && jsonObject.at(BUNDLE_INFO_APPID).is_string()) {
167 info.appId = jsonObject.at(BUNDLE_INFO_APPID).get<std::string>();
168 }
169 if ((jsonObject.find(BUNDLE_INFO_APP_INDEX) != jsonObject.end()) &&
170 jsonObject.at(BUNDLE_INFO_APP_INDEX).is_number()) {
171 info.appIndex = jsonObject.at(BUNDLE_INFO_APP_INDEX).get<int32_t>();
172 }
173 if (!ParseExtensionAbilityInfos(jsonObject, info.extensionInfos)) {
174 return false;
175 }
176 return true;
177 }
178
GetBundleInfo(const std::string & bundleName,const BundleFlag flag,BundleInfo & bundleInfo,int32_t userId)179 bool BundleManagerAdapterProxy::GetBundleInfo(
180 const std::string &bundleName, const BundleFlag flag, BundleInfo &bundleInfo, int32_t userId)
181 {
182 if (bundleName.empty()) {
183 ACCOUNT_LOGE("fail to GetBundleInfo due to params empty");
184 return false;
185 }
186
187 MessageParcel data;
188 if (!data.WriteInterfaceToken(GetDescriptor())) {
189 ACCOUNT_LOGE("fail to GetBundleInfo due to write InterfaceToken fail");
190 return false;
191 }
192 if (!data.WriteString(bundleName)) {
193 ACCOUNT_LOGE("fail to GetBundleInfo due to write bundleName fail");
194 return false;
195 }
196 if (!data.WriteInt32(static_cast<int>(flag))) {
197 ACCOUNT_LOGE("fail to GetBundleInfo due to write flag fail");
198 return false;
199 }
200 if (!data.WriteInt32(userId)) {
201 ACCOUNT_LOGE("fail to GetBundleInfo due to write userId fail");
202 return false;
203 }
204 return GetParcelInfo<BundleInfo>(BundleMgrInterfaceCode::GET_BUNDLE_INFO, data, bundleInfo);
205 }
206
GetUidByBundleName(const std::string & bundleName,const int userId)207 int BundleManagerAdapterProxy::GetUidByBundleName(const std::string &bundleName, const int userId)
208 {
209 if (bundleName.empty()) {
210 ACCOUNT_LOGE("failed to GetUidByBundleName due to bundleName empty");
211 return AppExecFwk::Constants::INVALID_UID;
212 }
213
214 MessageParcel data;
215 if (!data.WriteInterfaceToken(GetDescriptor())) {
216 ACCOUNT_LOGE("failed to GetUidByBundleName due to write InterfaceToken fail");
217 return AppExecFwk::Constants::INVALID_UID;
218 }
219 if (!data.WriteString(bundleName)) {
220 ACCOUNT_LOGE("failed to GetUidByBundleName due to write bundleName fail");
221 return AppExecFwk::Constants::INVALID_UID;
222 }
223 if (!data.WriteInt32(userId)) {
224 ACCOUNT_LOGE("failed to GetUidByBundleName due to write uid fail");
225 return AppExecFwk::Constants::INVALID_UID;
226 }
227
228 MessageParcel reply;
229 if (!SendTransactCmd(BundleMgrInterfaceCode::GET_UID_BY_BUNDLE_NAME, data, reply)) {
230 ACCOUNT_LOGE("failed to GetUidByBundleName from server");
231 return AppExecFwk::Constants::INVALID_UID;
232 }
233 int32_t uid = reply.ReadInt32();
234 return uid;
235 }
236
GetNameForUid(const int uid,std::string & bundleName)237 ErrCode BundleManagerAdapterProxy::GetNameForUid(const int uid, std::string &bundleName)
238 {
239 MessageParcel data;
240 if (!data.WriteInterfaceToken(GetDescriptor())) {
241 ACCOUNT_LOGE("fail to GetNameForUid due to write InterfaceToken fail");
242 return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
243 }
244 if (!data.WriteInt32(uid)) {
245 ACCOUNT_LOGE("fail to GetNameForUid due to write uid fail");
246 return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
247 }
248
249 MessageParcel reply;
250 if (!SendTransactCmd(BundleMgrInterfaceCode::GET_NAME_FOR_UID, data, reply)) {
251 ACCOUNT_LOGE("fail to GetNameForUid from server");
252 return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
253 }
254 ErrCode result;
255 if (!reply.ReadInt32(result)) {
256 ACCOUNT_LOGE("reply result false");
257 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
258 }
259 bundleName = reply.ReadString();
260 return result;
261 }
262
QueryAbilityInfos(const Want & want,int32_t flags,int32_t userId,std::vector<AbilityInfo> & abilityInfos)263 bool BundleManagerAdapterProxy::QueryAbilityInfos(
264 const Want &want, int32_t flags, int32_t userId, std::vector<AbilityInfo> &abilityInfos)
265 {
266 MessageParcel data;
267 if (!data.WriteInterfaceToken(GetDescriptor())) {
268 ACCOUNT_LOGE("fail to QueryAbilityInfos due to write MessageParcel fail");
269 return false;
270 }
271 if (!data.WriteParcelable(&want)) {
272 ACCOUNT_LOGE("fail to QueryAbilityInfos due to write want fail");
273 return false;
274 }
275 if (!data.WriteInt32(flags)) {
276 ACCOUNT_LOGE("fail to QueryAbilityInfos due to write flags fail");
277 return false;
278 }
279 if (!data.WriteInt32(userId)) {
280 ACCOUNT_LOGE("fail to QueryAbilityInfos due to write userId error");
281 return false;
282 }
283
284 if (!GetVectorFromParcelIntelligent<AbilityInfo>(BundleMgrInterfaceCode::QUERY_ABILITY_INFOS_MUTI_PARAM,
285 data, abilityInfos)) {
286 ACCOUNT_LOGE("fail to QueryAbilityInfos from server");
287 return false;
288 }
289 return true;
290 }
291
GetBundleUserMgr()292 sptr<IBundleUserMgr> BundleManagerAdapterProxy::GetBundleUserMgr()
293 {
294 MessageParcel data;
295 MessageParcel reply;
296 if (!data.WriteInterfaceToken(GetDescriptor())) {
297 ACCOUNT_LOGE("fail to get bundle user mgr due to write InterfaceToken fail");
298 return nullptr;
299 }
300 if (!SendTransactCmd(BundleMgrInterfaceCode::GET_BUNDLE_USER_MGR, data, reply)) {
301 return nullptr;
302 }
303
304 sptr<IRemoteObject> object = reply.ReadObject<IRemoteObject>();
305 if (object == nullptr) {
306 ACCOUNT_LOGE("read failed");
307 return nullptr;
308 }
309 sptr<IBundleUserMgr> bundleUserMgr = iface_cast<IBundleUserMgr>(object);
310 if (bundleUserMgr == nullptr) {
311 ACCOUNT_LOGE("bundleUserMgr is nullptr");
312 }
313
314 return bundleUserMgr;
315 }
316
QueryExtensionAbilityInfos(const Want & want,const int32_t & flag,const int32_t & userId,std::vector<ExtensionAbilityInfo> & extensionInfos)317 bool BundleManagerAdapterProxy::QueryExtensionAbilityInfos(const Want &want, const int32_t &flag,
318 const int32_t &userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
319 {
320 MessageParcel data;
321 if (!data.WriteInterfaceToken(GetDescriptor())) {
322 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write InterfaceToken fail");
323 return false;
324 }
325 if (!data.WriteParcelable(&want)) {
326 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write want fail");
327 return false;
328 }
329 if (!data.WriteInt32(flag)) {
330 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write flag fail");
331 return false;
332 }
333 if (!data.WriteInt32(userId)) {
334 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write userId fail");
335 return false;
336 }
337
338 if (!GetParcelableInfos(BundleMgrInterfaceCode::QUERY_EXTENSION_INFO_WITHOUT_TYPE, data, extensionInfos)) {
339 ACCOUNT_LOGE("fail to obtain extensionInfos");
340 return false;
341 }
342 return true;
343 }
344
QueryExtensionAbilityInfos(const Want & want,const ExtensionAbilityType & extensionType,const int32_t & flag,const int32_t & userId,std::vector<ExtensionAbilityInfo> & extensionInfos)345 bool BundleManagerAdapterProxy::QueryExtensionAbilityInfos(const Want &want, const ExtensionAbilityType &extensionType,
346 const int32_t &flag, const int32_t &userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
347 {
348 MessageParcel data;
349 if (!data.WriteInterfaceToken(GetDescriptor())) {
350 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write InterfaceToken fail");
351 return false;
352 }
353 if (!data.WriteParcelable(&want)) {
354 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write want fail");
355 return false;
356 }
357 if (!data.WriteInt32(static_cast<int32_t>(extensionType))) {
358 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write type fail");
359 return false;
360 }
361 if (!data.WriteInt32(flag)) {
362 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write flag fail");
363 return false;
364 }
365 if (!data.WriteInt32(userId)) {
366 ACCOUNT_LOGE("fail to QueryExtensionAbilityInfos due to write userId fail");
367 return false;
368 }
369
370 if (!GetParcelableInfos(BundleMgrInterfaceCode::QUERY_EXTENSION_INFO, data, extensionInfos)) {
371 ACCOUNT_LOGE("fail to obtain extensionInfos");
372 return false;
373 }
374 return true;
375 }
376
GetData(void * & buffer,size_t size,const void * data)377 bool BundleManagerAdapterProxy::GetData(void *&buffer, size_t size, const void *data)
378 {
379 if (data == nullptr) {
380 ACCOUNT_LOGE("GetData failed duo to null data");
381 return false;
382 }
383 if (size == 0) {
384 ACCOUNT_LOGE("GetData failed duo to zero size");
385 return false;
386 }
387 buffer = malloc(size);
388 if (buffer == nullptr) {
389 ACCOUNT_LOGE("GetData failed duo to malloc buffer failed");
390 return false;
391 }
392 if (memcpy_s(buffer, size, data, size) != EOK) {
393 free(buffer);
394 ACCOUNT_LOGE("GetData failed duo to memcpy_s failed");
395 return false;
396 }
397 return true;
398 }
399
400 template<typename T>
GetParcelInfo(BundleMgrInterfaceCode code,MessageParcel & data,T & parcelInfo)401 bool BundleManagerAdapterProxy::GetParcelInfo(BundleMgrInterfaceCode code, MessageParcel &data, T &parcelInfo)
402 {
403 MessageParcel reply;
404 if (!SendTransactCmd(code, data, reply)) {
405 ACCOUNT_LOGE("SendTransactCmd failed");
406 return false;
407 }
408
409 ErrCode ret = reply.ReadInt32();
410 if (ret != ERR_OK) {
411 ACCOUNT_LOGE("reply result failed , ret = %{public}d", ret);
412 return false;
413 }
414
415 return InnerGetParcelInfo<T>(reply, parcelInfo);
416 }
417
418 template<typename T>
InnerGetParcelInfo(MessageParcel & reply,T & parcelInfo)419 bool BundleManagerAdapterProxy::InnerGetParcelInfo(MessageParcel &reply, T &parcelInfo)
420 {
421 size_t dataSize = static_cast<size_t>(reply.ReadInt32());
422 void *buffer = nullptr;
423 if (!GetData(buffer, dataSize, reply.ReadRawData(dataSize))) {
424 ACCOUNT_LOGE("GetData failed");
425 return false;
426 }
427
428 MessageParcel tmpParcel;
429 if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), dataSize)) {
430 ACCOUNT_LOGE("ParseFrom failed");
431 return false;
432 }
433
434 std::unique_ptr<T> info(tmpParcel.ReadParcelable<T>());
435 if (info == nullptr) {
436 ACCOUNT_LOGE("ReadParcelableInfo failed");
437 return false;
438 }
439 parcelInfo = *info;
440 return true;
441 }
442
443 template<typename T>
GetParcelableInfo(BundleMgrInterfaceCode code,MessageParcel & data,T & parcelableInfo)444 bool BundleManagerAdapterProxy::GetParcelableInfo(BundleMgrInterfaceCode code, MessageParcel &data, T &parcelableInfo)
445 {
446 MessageParcel reply;
447 if (!SendTransactCmd(code, data, reply)) {
448 return false;
449 }
450
451 if (!reply.ReadBool()) {
452 ACCOUNT_LOGE("reply result false");
453 return false;
454 }
455
456 std::unique_ptr<T> info(reply.ReadParcelable<T>());
457 if (info == nullptr) {
458 ACCOUNT_LOGE("readParcelableInfo failed");
459 return false;
460 }
461 parcelableInfo = *info;
462
463 return true;
464 }
465
466 template <typename T>
GetBigParcelableInfo(BundleMgrInterfaceCode code,MessageParcel & data,T & parcelableInfo)467 bool BundleManagerAdapterProxy::GetBigParcelableInfo(
468 BundleMgrInterfaceCode code, MessageParcel &data, T &parcelableInfo)
469 {
470 MessageParcel reply;
471 if (!SendTransactCmd(code, data, reply)) {
472 return false;
473 }
474
475 if (!reply.ReadBool()) {
476 ACCOUNT_LOGE("reply result false");
477 return false;
478 }
479
480 if (reply.ReadBool()) {
481 ACCOUNT_LOGI("big reply, reading data from ashmem");
482 return GetParcelableFromAshmem<T>(reply, parcelableInfo);
483 }
484
485 std::unique_ptr<T> info(reply.ReadParcelable<T>());
486 if (info == nullptr) {
487 ACCOUNT_LOGE("readParcelableInfo failed");
488 return false;
489 }
490 parcelableInfo = *info;
491 ACCOUNT_LOGD("get parcelable info success");
492 return true;
493 }
494
495 template <typename T>
GetParcelableFromAshmem(MessageParcel & reply,T & parcelableInfo)496 bool BundleManagerAdapterProxy::GetParcelableFromAshmem(MessageParcel &reply, T &parcelableInfo)
497 {
498 sptr<Ashmem> ashmem = reply.ReadAshmem();
499 if (ashmem == nullptr) {
500 ACCOUNT_LOGE("Ashmem is nullptr");
501 return false;
502 }
503
504 bool ret = ashmem->MapReadOnlyAshmem();
505 if (!ret) {
506 ACCOUNT_LOGE("Map read only ashmem fail");
507 ClearAshmem(ashmem);
508 return false;
509 }
510
511 int32_t offset = 0;
512 const char* dataStr = static_cast<const char*>(
513 ashmem->ReadFromAshmem(ashmem->GetAshmemSize(), offset));
514 if (dataStr == nullptr) {
515 ACCOUNT_LOGE("Data is nullptr when read from ashmem");
516 ClearAshmem(ashmem);
517 return false;
518 }
519
520 std::string lenStr;
521 if (!ParseStr(dataStr, ASHMEM_LEN, offset, lenStr)) {
522 ACCOUNT_LOGE("Parse lenStr fail");
523 ClearAshmem(ashmem);
524 return false;
525 }
526
527 int32_t strLen = 0;
528 if (!StrToInt(lenStr, strLen)) {
529 ACCOUNT_LOGE("Convert lenStr failed");
530 ClearAshmem(ashmem);
531 return false;
532 }
533 offset += ASHMEM_LEN;
534 std::string infoStr;
535 if (!ParseStr(dataStr, strLen, offset, infoStr)) {
536 ACCOUNT_LOGE("Parse infoStr fail");
537 ClearAshmem(ashmem);
538 return false;
539 }
540
541 if (!ParseInfo(infoStr, parcelableInfo)) {
542 ACCOUNT_LOGE("Parse info from json fail");
543 ClearAshmem(ashmem);
544 return false;
545 }
546
547 ClearAshmem(ashmem);
548 ACCOUNT_LOGD("Get parcelable vector from ashmem success");
549 return true;
550 }
551
552 template <typename T>
GetParcelableInfoWithErrCode(BundleMgrInterfaceCode code,MessageParcel & data,T & parcelableInfo)553 ErrCode BundleManagerAdapterProxy::GetParcelableInfoWithErrCode(BundleMgrInterfaceCode code, MessageParcel &data,
554 T &parcelableInfo)
555 {
556 ACCOUNT_LOGE("not support interface!");
557 return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
558 }
559
560 template<typename T>
GetParcelableInfos(BundleMgrInterfaceCode code,MessageParcel & data,std::vector<T> & parcelableInfos)561 bool BundleManagerAdapterProxy::GetParcelableInfos(BundleMgrInterfaceCode code, MessageParcel &data,
562 std::vector<T> &parcelableInfos)
563 {
564 MessageParcel reply;
565 if (!SendTransactCmd(code, data, reply)) {
566 return false;
567 }
568
569 if (!reply.ReadBool()) {
570 ACCOUNT_LOGE("readParcelableInfo failed");
571 return false;
572 }
573
574 int32_t infoSize = reply.ReadInt32();
575 for (int32_t i = 0; i < infoSize; i++) {
576 std::unique_ptr<T> info(reply.ReadParcelable<T>());
577 if (info == nullptr) {
578 ACCOUNT_LOGE("Read Parcelable infos failed");
579 return false;
580 }
581 parcelableInfos.emplace_back(*info);
582 }
583 ACCOUNT_LOGI("get parcelable infos success");
584 return true;
585 }
586
587 template<typename T>
GetVectorFromParcelIntelligent(BundleMgrInterfaceCode code,MessageParcel & data,std::vector<T> & parcelableInfos)588 bool BundleManagerAdapterProxy::GetVectorFromParcelIntelligent(
589 BundleMgrInterfaceCode code, MessageParcel &data, std::vector<T> &parcelableInfos)
590 {
591 MessageParcel reply;
592 if (!SendTransactCmd(code, data, reply)) {
593 return false;
594 }
595
596 if (!reply.ReadBool()) {
597 ACCOUNT_LOGE("readParcelableInfo failed");
598 return false;
599 }
600
601 if (InnerGetVectorFromParcelIntelligent<T>(reply, parcelableInfos) != ERR_OK) {
602 ACCOUNT_LOGE("InnerGetVectorFromParcelIntelligent failed");
603 return false;
604 }
605
606 return true;
607 }
608
609 template<typename T>
InnerGetVectorFromParcelIntelligent(MessageParcel & reply,std::vector<T> & parcelableInfos)610 ErrCode BundleManagerAdapterProxy::InnerGetVectorFromParcelIntelligent(
611 MessageParcel &reply, std::vector<T> &parcelableInfos)
612 {
613 size_t dataSize = static_cast<size_t>(reply.ReadInt32());
614 if (dataSize == 0) {
615 ACCOUNT_LOGW("Parcel no data");
616 return ERR_OK;
617 }
618
619 void *buffer = nullptr;
620 if (!SendData(buffer, dataSize, reply.ReadRawData(dataSize))) {
621 ACCOUNT_LOGE("Fail to read raw data, length = %{public}zu", dataSize);
622 return ERR_APPEXECFWK_PARCEL_ERROR;
623 }
624
625 MessageParcel tempParcel;
626 if (!tempParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), dataSize)) {
627 ACCOUNT_LOGE("Fail to ParseFrom");
628 return ERR_APPEXECFWK_PARCEL_ERROR;
629 }
630
631 int32_t infoSize = tempParcel.ReadInt32();
632 for (int32_t i = 0; i < infoSize; i++) {
633 std::unique_ptr<T> info(tempParcel.ReadParcelable<T>());
634 if (info == nullptr) {
635 ACCOUNT_LOGE("Read Parcelable infos failed");
636 return false;
637 }
638 parcelableInfos.emplace_back(*info);
639 }
640
641 return ERR_OK;
642 }
643
644 template <typename T>
ParseAshmem(int32_t infoSize,const char * dataStr,int32_t offset,std::vector<T> & parcelableInfos)645 bool BundleManagerAdapterProxy::ParseAshmem(
646 int32_t infoSize, const char* dataStr, int32_t offset, std::vector<T> &parcelableInfos)
647 {
648 if (dataStr == nullptr) {
649 return false;
650 }
651 while (infoSize > 0) {
652 std::string lenStr;
653 if (!ParseStr(dataStr, ASHMEM_LEN, offset, lenStr)) {
654 return false;
655 }
656 int32_t strLen = 0;
657 if (!StrToInt(lenStr, strLen)) {
658 ACCOUNT_LOGE("Convert lenStr failed");
659 return false;
660 }
661 offset += ASHMEM_LEN;
662 std::string infoStr;
663 if (!ParseStr(dataStr, strLen, offset, infoStr)) {
664 return false;
665 }
666 T info;
667 if (!ParseInfo(infoStr, info)) {
668 return false;
669 }
670 parcelableInfos.emplace_back(info);
671 infoSize--;
672 offset += strLen;
673 }
674 return true;
675 }
676
677 template <typename T>
GetParcelableInfosFromAshmem(BundleMgrInterfaceCode code,MessageParcel & data,std::vector<T> & parcelableInfos)678 bool BundleManagerAdapterProxy::GetParcelableInfosFromAshmem(
679 BundleMgrInterfaceCode code, MessageParcel &data, std::vector<T> &parcelableInfos)
680 {
681 MessageParcel reply;
682 if (!SendTransactCmd(code, data, reply)) {
683 return false;
684 }
685 if (!reply.ReadBool()) {
686 return false;
687 }
688 int32_t infoSize = reply.ReadInt32();
689 if (infoSize > MAX_INFO_SIZE) {
690 ACCOUNT_LOGE("info size is too large");
691 return false;
692 }
693 sptr<Ashmem> ashmem = reply.ReadAshmem();
694 if (ashmem == nullptr) {
695 ACCOUNT_LOGE("Ashmem is nullptr");
696 return false;
697 }
698 if (!ashmem->MapReadOnlyAshmem()) {
699 ACCOUNT_LOGE("Map read only ashmem fail");
700 ClearAshmem(ashmem);
701 return false;
702 }
703 int32_t offset = 0;
704 const char* dataStr = static_cast<const char*>(
705 ashmem->ReadFromAshmem(ashmem->GetAshmemSize(), offset));
706 bool result = ParseAshmem(infoSize, dataStr, offset, parcelableInfos);
707 ClearAshmem(ashmem);
708 return result;
709 }
710
SendData(void * & buffer,size_t size,const void * data)711 bool BundleManagerAdapterProxy::SendData(void *&buffer, size_t size, const void *data)
712 {
713 if (data == nullptr) {
714 ACCOUNT_LOGE("data is nullptr");
715 return false;
716 }
717
718 if (size <= 0) {
719 ACCOUNT_LOGE("size is invalid");
720 return false;
721 }
722
723 buffer = malloc(size);
724 if (buffer == nullptr) {
725 ACCOUNT_LOGE("buffer malloc failed");
726 return false;
727 }
728
729 if (memcpy_s(buffer, size, data, size) != EOK) {
730 free(buffer);
731 ACCOUNT_LOGE("memcpy_s failed");
732 return false;
733 }
734
735 return true;
736 }
737
SendTransactCmd(BundleMgrInterfaceCode code,MessageParcel & data,MessageParcel & reply)738 bool BundleManagerAdapterProxy::SendTransactCmd(
739 BundleMgrInterfaceCode code, MessageParcel &data, MessageParcel &reply)
740 {
741 MessageOption option(MessageOption::TF_SYNC);
742
743 sptr<IRemoteObject> remote = Remote();
744 if (remote == nullptr) {
745 ACCOUNT_LOGE("fail to send transact cmd %{public}d due to remote object", code);
746 return false;
747 }
748 int32_t result = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
749 if (result != NO_ERROR) {
750 ACCOUNT_LOGE("receive error transact code %{public}d in transact cmd %{public}d", result, code);
751 return false;
752 }
753 return true;
754 }
755 } // namespace AccountSA
756 } // namespace OHOS
757