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