• 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 "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