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