1 /*
2  * Copyright (c) 2020 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_ms_feature.h"
17 
18 #include "ability_info_utils.h"
19 #include "appexecfwk_errors.h"
20 #include "bundle_info_utils.h"
21 #include "bundle_inner_interface.h"
22 #include "bundle_manager_service.h"
23 #include "bundle_message_id.h"
24 #include "convert_utils.h"
25 #include "ipc_skeleton.h"
26 #include "bundle_log.h"
27 #include "message.h"
28 #include "ohos_init.h"
29 #include "samgr_lite.h"
30 #include "securec.h"
31 #include "utils.h"
32 #include "want_utils.h"
33 
34 namespace OHOS {
35 #ifdef __LINUX__
36 constexpr static uint32_t MAX_IPC_STRING_LENGTH = 8192UL;
37 #endif
38 static BmsImpl g_bmsImpl = {
39     SERVER_IPROXY_IMPL_BEGIN,
40     .Invoke = BundleMsFeature::Invoke,
41     .QueryAbilityInfo = BundleMsFeature::QueryAbilityInfo,
42     .GetBundleInfo = BundleMsFeature::GetBundleInfo,
43     .GetBundleInfos = BundleMsFeature::GetBundleInfos,
44     .QueryKeepAliveBundleInfos = BundleMsFeature::QueryKeepAliveBundleInfos,
45     .GetBundleNameForUid = BundleMsFeature::GetBundleNameForUid,
46     .GetBundleSize = BundleMsFeature::GetBundleSize,
47     IPROXY_END
48 };
49 
50 BundleInvokeType BundleMsFeature::BundleMsInvokeFuc[BMS_INNER_BEGIN] {
51     QueryInnerAbilityInfo,
52     GetInnerBundleInfo,
53     ChangeInnerCallbackServiceId,
54     GetInnerBundleNameForUid,
55     HandleGetBundleInfos,
56     HandleGetBundleInfos,
57     HandleGetBundleInfos,
58     HasSystemCapability,
59     GetInnerBundleSize,
60     HandleGetBundleInfosLength,
61     HandleGetBundleInfosByIndex,
62     GetSystemAvailableCapabilities,
63 };
64 
GetBmsFeatureApi(Feature * feature)65 IUnknown *GetBmsFeatureApi(Feature *feature)
66 {
67     g_bmsImpl.bundleMsFeature = reinterpret_cast<BundleMsFeature *>(feature);
68     return GET_IUNKNOWN(g_bmsImpl);
69 }
70 
Init()71 static void Init()
72 {
73     SamgrLite *sm = SAMGR_GetInstance();
74     if (sm == nullptr) {
75         return;
76     }
77     sm->RegisterFeature(BMS_SERVICE, reinterpret_cast<Feature *>(BundleMsFeature::GetInstance()));
78     sm->RegisterFeatureApi(BMS_SERVICE, BMS_FEATURE,
79         GetBmsFeatureApi(reinterpret_cast<Feature *>(BundleMsFeature::GetInstance())));
80     HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS feature start success");
81 }
82 APP_FEATURE_INIT(Init);
83 
BundleMsFeature()84 BundleMsFeature::BundleMsFeature() : identity_()
85 {
86     this->Feature::GetName = BundleMsFeature::GetFeatureName;
87     this->Feature::OnInitialize = BundleMsFeature::OnFeatureInitialize;
88     this->Feature::OnStop = BundleMsFeature::OnFeatureStop;
89     this->Feature::OnMessage = BundleMsFeature::OnFeatureMessage;
90 }
91 
~BundleMsFeature()92 BundleMsFeature::~BundleMsFeature() {}
93 
GetFeatureName(Feature * feature)94 const char *BundleMsFeature::GetFeatureName(Feature *feature)
95 {
96     (void) feature;
97     return BMS_FEATURE;
98 }
99 
OnFeatureInitialize(Feature * feature,Service * parent,Identity identity)100 void BundleMsFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity)
101 {
102     if (feature == nullptr) {
103         return;
104     }
105     (reinterpret_cast<BundleMsFeature *>(feature))->identity_ = identity;
106     bool ret = GetInstance()->BundleServiceTaskInit();
107     HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS feature initialized, result is %d", ret);
108 }
109 
OnFeatureStop(Feature * feature,Identity identity)110 void BundleMsFeature::OnFeatureStop(Feature *feature, Identity identity)
111 {
112     (void) feature;
113     (void) identity;
114 }
115 
OnFeatureMessage(Feature * feature,Request * request)116 BOOL BundleMsFeature::OnFeatureMessage(Feature *feature, Request *request)
117 {
118     if (feature == nullptr || request == nullptr) {
119         return FALSE;
120     }
121     ManagerService::GetInstance().ServiceMsgProcess(request);
122     return TRUE;
123 }
124 
HasSystemCapability(const uint8_t funcId,IpcIo * req,IpcIo * reply)125 uint8_t BundleMsFeature::HasSystemCapability(const uint8_t funcId, IpcIo *req, IpcIo *reply)
126 {
127     if ((req == nullptr) || (reply == nullptr)) {
128         return ERR_APPEXECFWK_OBJECT_NULL;
129     }
130     size_t size = 0;
131     char *sysCapName = reinterpret_cast<char *>(ReadString(req, &size));
132     if (sysCapName == nullptr) {
133         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
134     }
135     bool hasSysCap = OHOS::ManagerService::GetInstance().HasSystemCapability(sysCapName);
136     if (hasSysCap) {
137         WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
138         return OHOS_SUCCESS;
139     }
140     return ERR_APPEXECFWK_OBJECT_NULL;
141 }
142 
GetSystemAvailableCapabilities(const uint8_t funcId,IpcIo * req,IpcIo * reply)143 uint8_t BundleMsFeature::GetSystemAvailableCapabilities(const uint8_t funcId, IpcIo *req, IpcIo *reply)
144 {
145     if ((req == nullptr) || (reply == nullptr)) {
146         return ERR_APPEXECFWK_OBJECT_NULL;
147     }
148 
149     char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN];
150     int32_t len = MAX_SYSCAP_NUM;
151     uint8_t errorCode = OHOS::ManagerService::GetInstance().GetSystemAvailableCapabilities(sysCaps, &len);
152     if (errorCode != OHOS_SUCCESS) {
153         return errorCode;
154     }
155     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
156     WriteInt32(reply, len);
157     for (int32_t index = 0; index < len; index++) {
158         WriteString(reply, sysCaps[index]);
159     }
160     return errorCode;
161 }
162 
QueryInnerAbilityInfo(const uint8_t funcId,IpcIo * req,IpcIo * reply)163 uint8_t BundleMsFeature::QueryInnerAbilityInfo(const uint8_t funcId, IpcIo *req, IpcIo *reply)
164 {
165     if ((req == nullptr) || (reply == nullptr)) {
166         return ERR_APPEXECFWK_OBJECT_NULL;
167     }
168     Want want;
169     if (memset_s(&want, sizeof(Want), 0, sizeof(Want)) != EOK) {
170         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS feature memset want failed");
171         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
172     }
173     if (!DeserializeWant(&want, req)) {
174         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS feature deserialize failed");
175         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
176     }
177     AbilityInfo abilityInfo;
178     if (memset_s(&abilityInfo, sizeof(AbilityInfo), 0, sizeof(AbilityInfo)) != EOK) {
179         ClearWant(&want);
180         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS feature memset ability info failed");
181         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
182     }
183     uint8_t errorCode = QueryAbilityInfo(&want, &abilityInfo);
184     ClearWant(&want);
185     if (errorCode != OHOS_SUCCESS) {
186         ClearAbilityInfo(&abilityInfo);
187         return errorCode;
188     }
189     char *str = ConvertUtils::ConvertAbilityInfoToString(&abilityInfo);
190     if (str == nullptr) {
191         ClearAbilityInfo(&abilityInfo);
192         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
193     }
194 #ifdef __LINUX__
195     if (strlen(str) > MAX_IPC_STRING_LENGTH) {
196         ClearAbilityInfo(&abilityInfo);
197         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
198     }
199 #endif
200     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
201     WriteString(reply, str);
202     ClearAbilityInfo(&abilityInfo);
203     return OHOS_SUCCESS;
204 }
205 
GetInnerBundleInfo(const uint8_t funcId,IpcIo * req,IpcIo * reply)206 uint8_t BundleMsFeature::GetInnerBundleInfo(const uint8_t funcId, IpcIo *req, IpcIo *reply)
207 {
208     if ((req == nullptr) || (reply == nullptr)) {
209         return ERR_APPEXECFWK_OBJECT_NULL;
210     }
211     size_t size = 0;
212     char *bundleName = reinterpret_cast<char *>(ReadString(req, &size));
213     if (bundleName == nullptr) {
214         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
215     }
216     BundleInfo bundleInfo;
217     if (memset_s(&bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)) != EOK) {
218         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
219     }
220     int32_t flag;
221     ReadInt32(req, &flag);
222     uint8_t errorCode = GetBundleInfo(bundleName, flag, &bundleInfo);
223     if (errorCode != OHOS_SUCCESS) {
224         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS GET_BUNDLE_INFO errorcode: %{public}d\n", errorCode);
225         return errorCode;
226     }
227     char *str = ConvertUtils::ConvertBundleInfoToString(&bundleInfo);
228     if (str == nullptr) {
229         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
230     }
231 #ifdef __LINUX__
232     if (strlen(str) > MAX_IPC_STRING_LENGTH) {
233         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
234     }
235 #endif
236     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
237     WriteString(reply, str);
238     return OHOS_SUCCESS;
239 }
240 
GetInnerBundleSize(const uint8_t funcId,IpcIo * req,IpcIo * reply)241 uint8_t BundleMsFeature::GetInnerBundleSize(const uint8_t funcId, IpcIo *req, IpcIo *reply)
242 {
243     if ((req == nullptr) || (reply == nullptr)) {
244         return ERR_APPEXECFWK_OBJECT_NULL;
245     }
246     size_t size = 0;
247     uint32_t bundleSize = 0;
248     char *bundleName = reinterpret_cast<char *>(ReadString(req, &size));
249     if (bundleName == nullptr) {
250         WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
251         WriteUint32(reply, bundleSize);
252         return OHOS_SUCCESS;
253     }
254     bundleSize = GetBundleSize(bundleName);
255     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
256     WriteUint32(reply, bundleSize);
257     return OHOS_SUCCESS;
258 }
259 
HandleGetBundleInfos(const uint8_t funcId,IpcIo * req,IpcIo * reply)260 uint8_t BundleMsFeature::HandleGetBundleInfos(const uint8_t funcId, IpcIo *req, IpcIo *reply)
261 {
262     if ((req == nullptr) || (reply == nullptr)) {
263         return ERR_APPEXECFWK_OBJECT_NULL;
264     }
265     BundleInfo *bundleInfos = nullptr;
266     char *metaDataKey = nullptr;
267     int32_t lengthOfBundleInfo = 0;
268     uint8_t errorCode = 0;
269     size_t length = 0;
270     if (funcId == GET_BUNDLE_INFOS) {
271         int32_t flag;
272         ReadInt32(req, &flag);
273         errorCode = GetBundleInfos(flag, &bundleInfos, &lengthOfBundleInfo);
274     } else if (funcId == QUERY_KEEPALIVE_BUNDLE_INFOS) {
275         errorCode = QueryKeepAliveBundleInfos(&bundleInfos, &lengthOfBundleInfo);
276     } else if (funcId == GET_BUNDLE_INFOS_BY_METADATA) {
277         metaDataKey = reinterpret_cast<char *>(ReadString(req, &length));
278         if (metaDataKey == nullptr) {
279             return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
280         }
281         errorCode = GetBundleInfosByMetaData(metaDataKey, &bundleInfos, &lengthOfBundleInfo);
282     } else {
283         return ERR_APPEXECFWK_COMMAND_ERROR;
284     }
285     if (errorCode != OHOS_SUCCESS) {
286         BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
287         return errorCode;
288     }
289     char *strs = ConvertUtils::ConvertBundleInfosToString(&bundleInfos, lengthOfBundleInfo);
290     if (strs == nullptr) {
291         BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
292         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
293     }
294 #ifdef __LINUX__
295     if (strlen(strs) > MAX_IPC_STRING_LENGTH) {
296         BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
297         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
298     }
299 #endif
300     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
301     WriteInt32(reply, lengthOfBundleInfo);
302     WriteString(reply, strs);
303     BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
304     return OHOS_SUCCESS;
305 }
306 
GetInnerBundleNameForUid(const uint8_t funcId,IpcIo * req,IpcIo * reply)307 uint8_t BundleMsFeature::GetInnerBundleNameForUid(const uint8_t funcId, IpcIo *req, IpcIo *reply)
308 {
309     if ((req == nullptr) || (reply == nullptr)) {
310         return ERR_APPEXECFWK_OBJECT_NULL;
311     }
312     char *bundleName = nullptr;
313     int32_t readUid;
314     ReadInt32(req, &readUid);
315     uint8_t errorCode = GetBundleNameForUid(readUid, &bundleName);
316     if (errorCode != OHOS_SUCCESS) {
317         AdapterFree(bundleName);
318         return errorCode;
319     }
320     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
321     WriteString(reply, bundleName);
322     AdapterFree(bundleName);
323     return errorCode;
324 }
325 
ChangeInnerCallbackServiceId(const uint8_t funcId,IpcIo * req,IpcIo * reply)326 uint8_t BundleMsFeature::ChangeInnerCallbackServiceId(const uint8_t funcId, IpcIo *req, IpcIo *reply)
327 {
328     if ((req == nullptr) || (reply == nullptr)) {
329         return ERR_APPEXECFWK_OBJECT_NULL;
330     }
331     bool flag;
332     ReadBool(req, &flag);
333     SvcIdentity svc;
334     if (!(ReadRemoteObject(req, &svc))) {
335         return ERR_APPEXECFWK_DESERIALIZATION_FAILED;
336     }
337 
338     auto svcIdentity = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
339     if (svcIdentity == nullptr) {
340         return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
341     }
342     *svcIdentity = svc;
343     Request request = {
344         .msgId = BUNDLE_CHANGE_CALLBACK,
345         .len = static_cast<int16>(sizeof(SvcIdentity)),
346         .data = reinterpret_cast<void *>(svcIdentity),
347         .msgValue = static_cast<uint32>(flag ? 1 : 0)
348     };
349     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
350     if (propRet != OHOS_SUCCESS) {
351         AdapterFree(svcIdentity);
352         return ERR_APPEXECFWK_UNINSTALL_FAILED_SEND_REQUEST_ERROR;
353     }
354     return ERR_OK;
355 }
356 
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)357 int32 BundleMsFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
358 {
359     if (req == nullptr) {
360         return ERR_APPEXECFWK_OBJECT_NULL;
361     }
362     WriteUint8(reply, static_cast<uint8_t>(funcId));
363     uint8_t ret = OHOS_SUCCESS;
364     if (funcId >= GET_BUNDLE_INFOS && funcId <= GET_BUNDLE_INFOS_BY_METADATA) {
365         ret = BundleMsInvokeFuc[GET_BUNDLE_INFOS](funcId, req, reply);
366     } else if (funcId >= QUERY_ABILITY_INFO && funcId <= GET_BUNDLENAME_FOR_UID) {
367         ret = BundleMsInvokeFuc[funcId](funcId, req, reply);
368     } else if (funcId >= CHECK_SYS_CAP && funcId <= GET_SYS_CAP) {
369         ret = BundleMsInvokeFuc[funcId](funcId, req, reply);
370     } else {
371         ret = ERR_APPEXECFWK_COMMAND_ERROR;
372     }
373 
374     if (ret != OHOS_SUCCESS) {
375         WriteUint8(reply, ret);
376     }
377     return ret;
378 }
379 
BundleServiceTaskInit()380 bool BundleMsFeature::BundleServiceTaskInit()
381 {
382     Request request = {
383         .msgId = BUNDLE_SERVICE_INITED,
384         .len = 0,
385         .data = nullptr,
386         .msgValue = 0
387     };
388     int32 propRet = SAMGR_SendRequest(&identity_, &request, nullptr);
389     if (propRet != OHOS_SUCCESS) {
390         return false;
391     }
392     return true;
393 }
394 
QueryAbilityInfo(const Want * want,AbilityInfo * abilityInfo)395 uint8_t BundleMsFeature::QueryAbilityInfo(const Want *want, AbilityInfo *abilityInfo)
396 {
397     if ((abilityInfo == nullptr) || (want == nullptr) || (want->element == nullptr)) {
398         return ERR_APPEXECFWK_OBJECT_NULL;
399     }
400 
401     BundleInfo *bundleInfo = OHOS::ManagerService::GetInstance().QueryBundleInfo(want->element->bundleName);
402     if (bundleInfo == nullptr) {
403         return ERR_APPEXECFWK_QUERY_NO_INFOS;
404     }
405 
406     if ((bundleInfo->abilityInfos == nullptr) || (bundleInfo->numOfAbility == 0)) {
407         return ERR_APPEXECFWK_QUERY_NO_INFOS;
408     }
409 
410     for (int32_t i = 0; i < bundleInfo->numOfAbility; ++i) {
411         if ((want->element->abilityName != nullptr) && ((bundleInfo->abilityInfos)[i].name != nullptr) &&
412             (strcmp(want->element->abilityName, (bundleInfo->abilityInfos)[i].name) == 0)) {
413             OHOS::AbilityInfoUtils::CopyAbilityInfo(abilityInfo, bundleInfo->abilityInfos[i]);
414             return OHOS_SUCCESS;
415         }
416     }
417     return ERR_APPEXECFWK_QUERY_NO_INFOS;
418 }
419 
GetBundleInfo(const char * bundleName,int32_t flags,BundleInfo * bundleInfo)420 uint8_t BundleMsFeature::GetBundleInfo(const char *bundleName, int32_t flags, BundleInfo *bundleInfo)
421 {
422     return OHOS::ManagerService::GetInstance().GetBundleInfo(bundleName, flags, *bundleInfo);
423 }
424 
GetBundleInfos(const int flags,BundleInfo ** bundleInfos,int32_t * len)425 uint8_t BundleMsFeature::GetBundleInfos(const int flags, BundleInfo **bundleInfos, int32_t *len)
426 {
427     return OHOS::ManagerService::GetInstance().GetBundleInfos(flags, bundleInfos, len);
428 }
429 
GetBundleSize(const char * bundleName)430 uint32_t BundleMsFeature::GetBundleSize(const char *bundleName)
431 {
432     return OHOS::ManagerService::GetInstance().GetBundleSize(bundleName);
433 }
434 
QueryKeepAliveBundleInfos(BundleInfo ** bundleInfos,int32_t * len)435 uint8_t BundleMsFeature::QueryKeepAliveBundleInfos(BundleInfo **bundleInfos, int32_t *len)
436 {
437     if ((bundleInfos == nullptr) || (len == nullptr)) {
438         return ERR_APPEXECFWK_OBJECT_NULL;
439     }
440     BundleInfo *allBundleInfos = nullptr;
441     int32_t numOfAllBundleInfos = 0;
442     uint8_t errorCode = GetBundleInfos(1, &allBundleInfos, &numOfAllBundleInfos);
443     if (errorCode != OHOS_SUCCESS) {
444         return errorCode;
445     }
446     *len = 0;
447     for (int32_t i = 0; i < numOfAllBundleInfos; i++) {
448         if (allBundleInfos[i].isKeepAlive && allBundleInfos[i].isSystemApp) {
449             (*len)++;
450         }
451     }
452 
453     if (*len == 0) {
454         BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
455         return ERR_APPEXECFWK_QUERY_NO_INFOS;
456     }
457     *bundleInfos = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo) * (*len)));
458     if (*bundleInfos == nullptr || memset_s(*bundleInfos, sizeof(BundleInfo) * (*len), 0,
459         sizeof(BundleInfo) * (*len)) != EOK) {
460         BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
461         return ERR_APPEXECFWK_QUERY_INFOS_INIT_ERROR;
462     }
463 
464     int32_t count = 0;
465     for (int32_t i = 0; i < numOfAllBundleInfos && count < *len; i++) {
466         if (allBundleInfos[i].isKeepAlive && allBundleInfos[i].isSystemApp) {
467             OHOS::BundleInfoUtils::CopyBundleInfo(1, *bundleInfos + count, allBundleInfos[i]);
468             count++;
469         }
470     }
471     BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
472     return OHOS_SUCCESS;
473 }
474 
CheckBundleInfoWithSpecialMetaData(const BundleInfo & bundleInfo,const char * metaDataKey)475 static bool CheckBundleInfoWithSpecialMetaData(const BundleInfo &bundleInfo, const char *metaDataKey)
476 {
477     if (metaDataKey == nullptr) {
478         return false;
479     }
480 
481     for (int32_t i = 0; i < bundleInfo.numOfModule; i++) {
482         for (int32_t j = 0; j < METADATA_SIZE; j++) {
483             if ((bundleInfo.moduleInfos[i].metaData[j] != nullptr) &&
484                 (bundleInfo.moduleInfos[i].metaData[j]->name != nullptr) &&
485                 strcmp(metaDataKey, bundleInfo.moduleInfos[i].metaData[j]->name) == 0) {
486                 return true;
487             }
488         }
489     }
490     return false;
491 }
492 
GetBundleInfosByMetaData(const char * metaDataKey,BundleInfo ** bundleInfos,int32_t * len)493 uint8_t BundleMsFeature::GetBundleInfosByMetaData(const char *metaDataKey, BundleInfo **bundleInfos, int32_t *len)
494 {
495     if (metaDataKey == nullptr || bundleInfos == nullptr) {
496         return ERR_APPEXECFWK_OBJECT_NULL;
497     }
498 
499     BundleInfo *allBundleInfos = nullptr;
500     int32_t numOfAllBundleInfos = 0;
501     uint8_t errorCode = GetBundleInfos(1, &allBundleInfos, &numOfAllBundleInfos);
502     if (errorCode != OHOS_SUCCESS) {
503         return errorCode;
504     }
505     *len = 0;
506     for (int32_t i = 0; i < numOfAllBundleInfos; i++) {
507         if (CheckBundleInfoWithSpecialMetaData(allBundleInfos[i], metaDataKey)) {
508             (*len)++;
509         }
510     }
511 
512     if (*len == 0) {
513         BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
514         return ERR_APPEXECFWK_QUERY_NO_INFOS;
515     }
516 
517     *bundleInfos = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo) * (*len)));
518     if (*bundleInfos == nullptr || memset_s(*bundleInfos, sizeof(BundleInfo) * (*len), 0,
519         sizeof(BundleInfo) * (*len)) != EOK) {
520         BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
521         return ERR_APPEXECFWK_QUERY_INFOS_INIT_ERROR;
522     }
523 
524     int32_t count = 0;
525     for (int32_t i = 0; i < numOfAllBundleInfos && count < *len; i++) {
526         if (CheckBundleInfoWithSpecialMetaData(allBundleInfos[i], metaDataKey)) {
527             BundleInfoUtils::CopyBundleInfo(1, *bundleInfos + count, allBundleInfos[i]);
528             count++;
529         }
530     }
531     BundleInfoUtils::FreeBundleInfos(allBundleInfos, numOfAllBundleInfos);
532     return OHOS_SUCCESS;
533 }
534 
GetBundleNameForUid(int32_t uid,char ** bundleName)535 uint8_t BundleMsFeature::GetBundleNameForUid(int32_t uid, char **bundleName)
536 {
537     if (bundleName == nullptr) {
538         return ERR_APPEXECFWK_OBJECT_NULL;
539     }
540     BundleInfo *infos = nullptr;
541     int32_t numOfInfos = 0;
542     uint8_t errorCode = GetBundleInfos(0, &infos, &numOfInfos);
543     if (errorCode != OHOS_SUCCESS) {
544         BundleInfoUtils::FreeBundleInfos(infos, numOfInfos);
545         return errorCode;
546     }
547 
548     for (int i = 0; i < numOfInfos; ++i) {
549         if (infos[i].uid == uid) {
550             *bundleName = Utils::Strdup(infos[i].bundleName);
551             break;
552         }
553     }
554     BundleInfoUtils::FreeBundleInfos(infos, numOfInfos);
555     if (*bundleName == nullptr) {
556         return ERR_APPEXECFWK_NO_BUNDLENAME_FOR_UID;
557     }
558     return OHOS_SUCCESS;
559 }
560 
GetInnerBundleInfos(IpcIo * req,IpcIo * reply,int32_t * length)561 BundleInfo *BundleMsFeature::GetInnerBundleInfos(IpcIo *req, IpcIo *reply, int32_t *length)
562 {
563     HILOG_INFO(HILOG_MODULE_APP, "BundleMS GetInnerBundleInfos start");
564     if ((req == nullptr) || (reply == nullptr)) {
565         return nullptr;
566     }
567     BundleInfo *bundleInfos = nullptr;
568     uint8_t errorCode = 0;
569     int32_t codeFlag = -1;
570     ReadInt32(req, &codeFlag);
571     if (codeFlag == GET_BUNDLE_INFOS) {
572         int32_t flag;
573         ReadInt32(req, &flag);
574         errorCode = GetBundleInfos(flag, &bundleInfos, length);
575     } else if (codeFlag == QUERY_KEEPALIVE_BUNDLE_INFOS) {
576         errorCode = QueryKeepAliveBundleInfos(&bundleInfos, length);
577     } else if (codeFlag == GET_BUNDLE_INFOS_BY_METADATA) {
578         size_t len = 0;
579         char *metaDataKey = reinterpret_cast<char *>(ReadString(req, &len));
580         if (metaDataKey == nullptr) {
581             return nullptr;
582         }
583         errorCode = GetBundleInfosByMetaData(metaDataKey, &bundleInfos, length);
584     } else {
585         return nullptr;
586     }
587     if (errorCode != OHOS_SUCCESS) {
588         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS GetInnerBundleInfos failed with errorcode: %{public}d\n", errorCode);
589         BundleInfoUtils::FreeBundleInfos(bundleInfos, *length);
590         return nullptr;
591     }
592     HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS GetInnerBundleInfos with length is: %{public}d\n", *length);
593     return bundleInfos;
594 }
595 
HandleGetBundleInfosLength(const uint8_t funcId,IpcIo * req,IpcIo * reply)596 uint8_t BundleMsFeature::HandleGetBundleInfosLength(const uint8_t funcId, IpcIo *req, IpcIo *reply)
597 {
598     HILOG_INFO(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosLength start");
599     if ((req == nullptr) || (reply == nullptr)) {
600         return ERR_APPEXECFWK_OBJECT_NULL;
601     }
602     int32_t lengthOfBundleInfo = 0;
603     BundleInfo *bundleInfos = GetInnerBundleInfos(req, reply, &lengthOfBundleInfo);
604     if (bundleInfos == nullptr) {
605         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS bundleInfos is nullptr");
606         return ERR_APPEXECFWK_OBJECT_NULL;
607     }
608     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
609     WriteInt32(reply, lengthOfBundleInfo);
610     BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
611     HILOG_INFO(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosLength finished");
612     return OHOS_SUCCESS;
613 }
614 
HandleGetBundleInfosByIndex(const uint8_t funcId,IpcIo * req,IpcIo * reply)615 uint8_t BundleMsFeature::HandleGetBundleInfosByIndex(const uint8_t funcId, IpcIo *req, IpcIo *reply)
616 {
617     HILOG_INFO(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosByIndex start");
618     if ((req == nullptr) || (reply == nullptr)) {
619         return ERR_APPEXECFWK_OBJECT_NULL;
620     }
621     int32_t lengthOfBundleInfo = 0;
622     BundleInfo *bundleInfos = GetInnerBundleInfos(req, reply, &lengthOfBundleInfo);
623     int32_t index = 0;
624     ReadInt32(req, &index);
625     HILOG_INFO(HILOG_MODULE_APP, "BundleMS index is : %{public}d\n", index);
626     char *str = ConvertUtils::ConvertBundleInfoToString(bundleInfos + index);
627     if (str == nullptr) {
628         BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
629         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosByIndex strs is nullptr");
630         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
631     }
632     HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS length of str is: %{public}d\n", static_cast<int32_t>(strlen(str)));
633 #ifdef __LINUX__
634     if (strlen(str) > MAX_IPC_STRING_LENGTH) {
635         BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
636         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosByIndex is too larger to be transformed by ipc");
637         cJSON_free(str);
638         return ERR_APPEXECFWK_SERIALIZATION_FAILED;
639     }
640 #endif
641     WriteUint8(reply, static_cast<uint8_t>(OHOS_SUCCESS));
642     WriteString(reply, str);
643     HILOG_INFO(HILOG_MODULE_APP, "BundleMS bundleInfo length is %{public}d of index %{public}d",
644         static_cast<int32_t>(strlen(str)), index);
645     BundleInfoUtils::FreeBundleInfos(bundleInfos, lengthOfBundleInfo);
646 
647     cJSON_free(str);
648     HILOG_INFO(HILOG_MODULE_APP, "BundleMS HandleGetBundleInfosByIndex finished");
649     return OHOS_SUCCESS;
650 }
651 } // namespace OHOS
652