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_manager_service.h"
17 
18 #include "app_verify_pub.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 #ifdef __cplusplus
24 }
25 #endif
26 
27 #include <algorithm>
28 #include <dirent.h>
29 #include <pthread.h>
30 #include <unistd.h>
31 
32 #include "appexecfwk_errors.h"
33 #include "bundle_callback_utils.h"
34 #include "bundle_common.h"
35 #include "bundle_daemon_client.h"
36 #include "bundle_info_utils.h"
37 #include "bundle_inner_feature.h"
38 #include "bundle_manager.h"
39 #include "bundle_message_id.h"
40 #include "bundle_parser.h"
41 #include "bundle_util.h"
42 #include "ipc_skeleton.h"
43 #include "rpc_errno.h"
44 #include "bundle_log.h"
45 #include "samgr_lite.h"
46 #include "utils.h"
47 #include "want.h"
48 
49 namespace OHOS {
ManagerService()50 ManagerService::ManagerService()
51 {
52     installer_ = new (std::nothrow) BundleInstaller(INSTALL_PATH, DATA_PATH);
53     bundleMap_ = BundleMap::GetInstance();
54 }
55 
~ManagerService()56 ManagerService::~ManagerService()
57 {
58     if (installer_ != nullptr) {
59         delete installer_;
60         installer_ = nullptr;
61     }
62     sysUidMap_.clear();
63     sysVendorUidMap_.clear();
64     appUidMap_.clear();
65 }
66 
InnerTransact(uint32_t code,uint8_t resultCode,const char * bundleName)67 static void InnerTransact(uint32_t code, uint8_t resultCode, const char *bundleName)
68 {
69     if (bundleName == nullptr) {
70         return;
71     }
72     IpcIo io;
73     char data[MAX_IO_SIZE];
74     IpcIo reply;
75     uintptr_t ptr;
76     IpcIoInit(&io, data, MAX_IO_SIZE, 0);
77     WriteInt32(&io, static_cast<int32_t>(resultCode));
78     WriteString(&io, bundleName);
79     std::vector<SvcIdentity> svcIdentity = ManagerService::GetInstance().GetServiceId();
80     if (svcIdentity.empty()) {
81         return;
82     }
83     MessageOption option;
84     MessageOptionInit(&option);
85     option.flags = TF_OP_ASYNC;
86     for (const auto& svc : svcIdentity) {
87         int32_t ret = SendRequest(svc, code, &io, &reply, option, &ptr);
88         if (ret != ERR_NONE) {
89             HILOG_ERROR(HILOG_MODULE_APP, "BundleMS InnerTransact failed %{public}d\n", ret);
90             return;
91         }
92     }
93 }
94 
InnerSelfTransact(uint32_t code,uint8_t resultCode,const SvcIdentity & svc)95 static void InnerSelfTransact(uint32_t code, uint8_t resultCode, const SvcIdentity &svc)
96 {
97     IpcIo io;
98     char data[MAX_IO_SIZE];
99     IpcIo reply;
100     IpcIoInit(&io, data, MAX_IO_SIZE, 0);
101     WriteInt32(&io, static_cast<int32_t>(resultCode));
102 
103     MessageOption option;
104     MessageOptionInit(&option);
105     option.flags = TF_OP_ASYNC;
106     int32_t ret = SendRequest(svc, code, &io, &reply, option, NULL);
107     if (ret != ERR_NONE) {
108         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS InnerSelfTransact failed %{public}d\n", ret);
109     }
110     ReleaseSvc(svc);
111 }
112 
GetServiceId() const113 std::vector<SvcIdentity> ManagerService::GetServiceId() const
114 {
115     return svcIdentity_;
116 }
117 
GetAmsInterface(AmsInnerInterface ** amsInterface)118 bool ManagerService::GetAmsInterface(AmsInnerInterface **amsInterface)
119 {
120     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE);
121     if (iUnknown == NULL) {
122         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS GetAmsInterface failed");
123         return false;
124     }
125 
126     int result = iUnknown->QueryInterface(iUnknown, 0, reinterpret_cast<void **>(amsInterface));
127     if (result != 0) {
128         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS Query ams Interface failed: %{public}d\n", result);
129         return false;
130     }
131 
132     return true;
133 }
134 
SetExternalInstallMode(bool enable)135 uint8_t ManagerService::SetExternalInstallMode(bool enable)
136 {
137     IsExternalInstallMode_ = enable;
138     HILOG_INFO(HILOG_MODULE_APP, "current install mode is %d", IsExternalInstallMode_);
139     return ERR_OK;
140 }
141 
IsExternalInstallMode() const142 bool ManagerService::IsExternalInstallMode() const
143 {
144     return IsExternalInstallMode_;
145 }
146 
SetDebugMode(bool enable)147 uint8_t ManagerService::SetDebugMode(bool enable)
148 {
149     int32_t ret = APPVERI_SetDebugMode(enable);
150     if (ret < 0) {
151         HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed");
152         return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR;
153     }
154     isDebugMode_ = enable;
155     HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_);
156     return ERR_OK;
157 }
158 
IsDebugMode() const159 bool ManagerService::IsDebugMode() const
160 {
161     return isDebugMode_;
162 }
163 
164 #ifdef OHOS_DEBUG
SetSignMode(bool enable)165 uint8_t ManagerService::SetSignMode(bool enable)
166 {
167     isSignMode_ = enable;
168     HILOG_INFO(HILOG_MODULE_APP, "current sign mode is %d", isSignMode_);
169     return ERR_OK;
170 }
171 
IsSignMode() const172 bool ManagerService::IsSignMode() const
173 {
174     return isSignMode_;
175 }
176 #endif
177 
ServiceMsgProcess(Request * request)178 void ManagerService::ServiceMsgProcess(Request* request)
179 {
180     if (request == nullptr) {
181         return;
182     }
183 
184     if (installer_ == nullptr) {
185         installer_ = new (std::nothrow) BundleInstaller(INSTALL_PATH, DATA_PATH);
186     }
187 
188     switch (request->msgId) {
189         case BUNDLE_SERVICE_INITED: {
190             if (!BundleDaemonClient::GetInstance().Initialize()) {
191                 HILOG_ERROR(HILOG_MODULE_APP, "BundleDeamonClient initialize fail");
192                 return;
193             }
194             ScanPackages();
195             ScanSharedLibPath();
196             AmsInnerInterface *amsInterface = nullptr;
197             if (!GetAmsInterface(&amsInterface)) {
198                 return;
199             }
200             if (amsInterface != nullptr) {
201                 amsInterface->StartKeepAliveApps();
202             }
203             break;
204         }
205         case BUNDLE_UPDATED:
206             /* Process update request by Install() */
207         case BUNDLE_INSTALLED: {
208             auto info = reinterpret_cast<SvcIdentityInfo *>(request->data);
209             if (info == nullptr) {
210                 return;
211             }
212             if (info->svc == nullptr || info->path == nullptr) {
213                 AdapterFree(info->path);
214                 AdapterFree(info->svc);
215                 return;
216             }
217 
218             InstallThirdBundle(info->path, *(info->svc), info->installLocation);
219             AdapterFree(info->path);
220             AdapterFree(info->svc);
221             break;
222         }
223         case BUNDLE_UNINSTALLED: {
224             auto info = reinterpret_cast<SvcIdentityInfo *>(request->data);
225             if (info == nullptr) {
226                 return;
227             }
228             if ((info->bundleName == nullptr) || (info->svc == nullptr)) {
229                 AdapterFree(info->bundleName);
230                 AdapterFree(info->svc);
231                 return;
232             }
233 
234             InstallParam installParam = {.installLocation = 1, .keepData = info->keepData};
235             uint8_t bResult = installer_->Uninstall(info->bundleName, installParam);
236             InnerSelfTransact(UNINSTALL_CALLBACK, bResult, *(info->svc));
237             InnerTransact(UNINSTALL_CALLBACK, bResult, info->bundleName);
238             if (bResult == ERR_OK) {
239                 RecycleUid(info->bundleName);
240             }
241             AdapterFree(info->bundleName);
242             AdapterFree(info->svc);
243             break;
244         }
245         case BUNDLE_CHANGE_CALLBACK: {
246             auto svc = reinterpret_cast<SvcIdentity *>(request->data);
247             if (svc == nullptr) {
248                 return;
249             }
250             if (request->msgValue) {
251                 AddCallbackServiceId(*svc);
252             } else {
253                 RemoveCallbackServiceId(*svc);
254             }
255             break;
256         }
257         default: {
258             break;
259         }
260     }
261 }
262 
CompareServiceId(const SvcIdentity & svc1,const SvcIdentity & svc2)263 static bool CompareServiceId(const SvcIdentity &svc1, const SvcIdentity &svc2)
264 {
265     return (svc1.handle == svc2.handle) && (svc1.token == svc2.token);
266 }
267 
AddCallbackServiceId(const SvcIdentity & svc)268 void ManagerService::AddCallbackServiceId(const SvcIdentity &svc)
269 {
270     for (auto it = svcIdentity_.begin(); it != svcIdentity_.end(); ++it) {
271         if (CompareServiceId(*it, svc)) {
272             return;
273         }
274     }
275     svcIdentity_.emplace_back(svc);
276 }
277 
RemoveCallbackServiceId(const SvcIdentity & svc)278 void ManagerService::RemoveCallbackServiceId(const SvcIdentity &svc)
279 {
280     ReleaseSvc(svc);
281     for (auto it = svcIdentity_.begin(); it != svcIdentity_.end(); ++it) {
282         if (CompareServiceId(*it, svc)) {
283             svcIdentity_.erase(it);
284             return;
285         }
286     }
287 }
288 
InstallThirdBundle(const char * path,const SvcIdentity & svc,int32_t installLocation)289 void ManagerService::InstallThirdBundle(const char *path, const SvcIdentity &svc, int32_t installLocation)
290 {
291     if (path == nullptr || installer_ == nullptr) {
292         return;
293     }
294     char *bundleName = nullptr;
295     int32_t versionCode = -1;
296     int8_t ret = BundleParser::ParseBundleParam(path, &bundleName, versionCode);
297     if (ret != ERR_OK) {
298         InnerSelfTransact(INSTALL_CALLBACK, ret, svc);
299         AdapterFree(bundleName);
300         return;
301     }
302     InstallParam installParam = {.installLocation = installLocation, .keepData = false};
303     uint8_t bResult = installer_->Install(path, installParam);
304     HILOG_DEBUG(HILOG_MODULE_APP, "BundleMS InstallThirdBundle Install : %{public}d\n", bResult);
305     InnerSelfTransact(INSTALL_CALLBACK, bResult, svc);
306     InnerTransact(INSTALL_CALLBACK, bResult, bundleName);
307 }
308 
InstallAllSystemBundle(int32_t scanFlag)309 void ManagerService::InstallAllSystemBundle(int32_t scanFlag)
310 {
311     DIR *dir = nullptr;
312     dirent *ent = nullptr;
313 
314     dir = (scanFlag == SYSTEM_APP_FLAG) ? opendir(SYSTEM_BUNDLE_PATH) : opendir(THIRD_SYSTEM_BUNDLE_PATH);
315     if (dir == nullptr) {
316         return;
317     }
318 
319     while ((ent = readdir(dir)) != nullptr) {
320         if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..")) == 0) {
321             continue;
322         }
323         if (scanFlag == SYSTEM_APP_FLAG) {
324             InstallSystemBundle(SYSTEM_BUNDLE_PATH, ent->d_name);
325         } else {
326             InstallSystemBundle(THIRD_SYSTEM_BUNDLE_PATH, ent->d_name);
327         }
328     }
329     closedir(dir);
330 }
331 
InstallSystemBundle(const char * fileDir,const char * fileName)332 void ManagerService::InstallSystemBundle(const char *fileDir, const char *fileName)
333 {
334     if ((installer_ == nullptr) || (fileDir == nullptr) || (fileName == nullptr)) {
335         return;
336     }
337     std::string systemAppPath = std::string(fileDir) + PATH_SEPARATOR + fileName;
338     if (!BundleUtil::IsFile(systemAppPath.c_str()) ||
339         !BundleUtil::EndWith(systemAppPath.c_str(), INSTALL_FILE_SUFFIX)) {
340         return;
341     }
342     InstallParam installParam = {.installLocation = 1, .keepData = false};
343     uint8_t ret = installer_->Install(systemAppPath.c_str(), installParam);
344     HILOG_INFO(HILOG_MODULE_APP, "install system app, result is : %{public}d", ret);
345 }
346 
ScanPackages()347 void ManagerService::ScanPackages()
348 {
349     // restore uid and gid map
350     RestoreUidAndGidMap();
351 
352     if (!BundleUtil::IsDir(JSON_PATH)) {
353         InstallAllSystemBundle(SYSTEM_APP_FLAG);
354         InstallAllSystemBundle(THIRD_SYSTEM_APP_FLAG);
355         return;
356     }
357 
358     // get third system bundle uninstall record
359     cJSON *uninstallRecord = BundleUtil::GetJsonStream(UNINSTALL_THIRD_SYSTEM_BUNDLE_JSON);
360     if (uninstallRecord == nullptr) {
361         BundleDaemonClient::GetInstance().RemoveFile(UNINSTALL_THIRD_SYSTEM_BUNDLE_JSON);
362     }
363 
364     // scan system apps
365     ScanAppDir(SYSTEM_BUNDLE_PATH, nullptr, SYSTEM_APP_FLAG);
366     // scan third system apps
367     ScanAppDir(THIRD_SYSTEM_BUNDLE_PATH, uninstallRecord, THIRD_SYSTEM_APP_FLAG);
368     if (uninstallRecord != nullptr) {
369         cJSON_Delete(uninstallRecord);
370         uninstallRecord = nullptr;
371     }
372     // scan third apps
373     ScanAppDir(INSTALL_PATH, nullptr, THIRD_APP_FLAG);
374     // scan third apps in sdcard if exists
375     if (BundleUtil::IsDir(EXTEANAL_INSTALL_PATH)) {
376         ScanAppDir(EXTEANAL_INSTALL_PATH, nullptr, THIRD_APP_FLAG);
377     }
378 }
379 
ScanAppDir(const char * appDir,const cJSON * uninstallRecord,uint8_t scanFlag)380 void ManagerService::ScanAppDir(const char *appDir, const cJSON *uninstallRecord, uint8_t scanFlag)
381 {
382     dirent *ent = nullptr;
383     char *bundleName = nullptr;
384     int32_t versionCode = -1;
385 
386     if (appDir == nullptr) {
387         return;
388     }
389 
390     DIR *dir = opendir(appDir);
391     if (dir == nullptr) {
392         return;
393     }
394     while ((ent = readdir(dir)) != nullptr) {
395         if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..")) == 0) {
396             continue;
397         }
398         std::string appPath = std::string(appDir) + PATH_SEPARATOR + ent->d_name;
399         if (scanFlag == THIRD_APP_FLAG) {
400             if (!BundleUtil::IsDir(appPath.c_str())) {
401                 continue;
402             }
403             ReloadEntireBundleInfo(appPath.c_str(), ent->d_name, versionCode, scanFlag);
404             continue;
405         }
406 
407         // scan system app
408         bool res = CheckSystemBundleIsValid(appPath.c_str(), &bundleName, versionCode);
409         if (!res) {
410             AdapterFree(bundleName);
411             continue;
412         }
413 
414         if (scanFlag == THIRD_SYSTEM_APP_FLAG &&
415             CheckThirdSystemBundleHasUninstalled(bundleName, uninstallRecord)) {
416             AdapterFree(bundleName);
417             continue;
418         }
419         ReloadEntireBundleInfo(appPath.c_str(), bundleName, versionCode, scanFlag);
420         AdapterFree(bundleName);
421     }
422     closedir(dir);
423 }
424 
CheckSystemBundleIsValid(const char * appPath,char ** bundleName,int32_t & versionCode)425 bool ManagerService::CheckSystemBundleIsValid(const char *appPath, char **bundleName, int32_t &versionCode)
426 {
427     if (appPath == nullptr || bundleName == nullptr) {
428         return false;
429     }
430 
431     if (!BundleUtil::EndWith(appPath, INSTALL_FILE_SUFFIX)) {
432         return false;
433     }
434 
435     if (BundleParser::ParseBundleParam(appPath, bundleName, versionCode) != 0) {
436         return false;
437     }
438 
439     if (*bundleName != nullptr && strlen(*bundleName) > MAX_BUNDLE_NAME_LEN) {
440         return false;
441     }
442     return true;
443 }
444 
ReloadEntireBundleInfo(const char * appPath,const char * bundleName,int32_t versionCode,uint8_t scanFlag)445 void ManagerService::ReloadEntireBundleInfo(const char *appPath, const char *bundleName, int32_t versionCode,
446     uint8_t scanFlag)
447 {
448     char *codePath = nullptr;
449     char *appId = nullptr;
450     int32_t oldVersionCode = -1;
451     InstallParam installParam = {.installLocation = 1, .keepData = false};
452 
453     if (appPath == nullptr || bundleName == nullptr || installer_ == nullptr) {
454         return;
455     }
456 
457     if (QueryBundleInfo(bundleName) != nullptr) {
458         return;
459     }
460 
461     bool res = BundleUtil::CheckBundleJsonIsValid(bundleName, &codePath, &appId, oldVersionCode);
462     bool isSystemApp = (scanFlag == SYSTEM_APP_FLAG);
463     if (scanFlag != THIRD_APP_FLAG) {
464         if (!res) {
465             uint8_t ret = installer_->Install(appPath, installParam);
466             HILOG_INFO(HILOG_MODULE_APP, "install new system app, result is %d", ret);
467             AdapterFree(codePath);
468             AdapterFree(appId);
469             return;
470         }
471         if (versionCode > oldVersionCode) {
472             ReloadBundleInfo(codePath, appId, bundleName, isSystemApp);
473             uint8_t ret = installer_->Install(appPath, installParam);
474             HILOG_INFO(HILOG_MODULE_APP, "update system app, result is %d", ret);
475             AdapterFree(codePath);
476             AdapterFree(appId);
477             return;
478         }
479     } else {
480         if (!res) {
481             HILOG_ERROR(HILOG_MODULE_APP, "codePath or appid in third app json file is invalid!");
482             AdapterFree(codePath);
483             AdapterFree(appId);
484             return;
485         }
486     }
487     ReloadBundleInfo(codePath, appId, bundleName, isSystemApp);
488     AdapterFree(appId);
489     AdapterFree(codePath);
490 }
491 
ReloadBundleInfo(const char * codePath,const char * appId,const char * bundleName,bool isSystemApp)492 void ManagerService::ReloadBundleInfo(const char *codePath, const char *appId, const char *bundleName,
493     bool isSystemApp)
494 {
495     BundleParser bundleParser;
496     dirent *ent = nullptr;
497 
498     int32_t uid = BundleUtil::GetValueFromBundleJson(bundleName, JSON_SUB_KEY_UID, INVALID_UID);
499     int32_t gid = uid;
500     if (uid == INVALID_UID || gid == INVALID_GID) {
501         HILOG_ERROR(HILOG_MODULE_APP, "get uid or gid in json file fail!");
502         return;
503     }
504 
505     DIR *dir = opendir(codePath);
506     if (dir == nullptr) {
507         return;
508     }
509 
510     while ((ent = readdir(dir)) != nullptr) {
511         if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..")) == 0) {
512             continue;
513         }
514         std::string profileDir = codePath + std::string(PATH_SEPARATOR) + ent->d_name;
515         BundleInfo *bundleInfo = bundleParser.ParseHapProfile(profileDir.c_str());
516         if (bundleInfo != nullptr) {
517             bundleInfo->isSystemApp = isSystemApp;
518             bundleInfo->appId = Utils::Strdup(appId);
519             if (bundleInfo->appId == nullptr) {
520                 HILOG_ERROR(HILOG_MODULE_APP, "bundleInfo->appId is nullptr when restore bundleInfo!");
521                 BundleInfoUtils::FreeBundleInfo(bundleInfo);
522                 continue;
523             }
524             bundleInfo->uid = static_cast<int32_t>(uid);
525             bundleInfo->gid = static_cast<int32_t>(gid);
526             // need to update bundleInfo when support many haps install
527             bundleMap_->Add(bundleInfo);
528         } else {
529             BundleDaemonClient::GetInstance().RemoveFile(profileDir.c_str());
530             // delete uid and gid info
531             BundleUtil::DeleteUidInfoFromJson(bundleName);
532         }
533     }
534     closedir(dir);
535 }
536 
CheckThirdSystemBundleHasUninstalled(const char * bundleName,const cJSON * object)537 bool ManagerService::CheckThirdSystemBundleHasUninstalled(const char *bundleName, const cJSON *object)
538 {
539     if (object == nullptr || bundleName == nullptr) {
540         return false;
541     }
542 
543     cJSON *array = cJSON_GetObjectItem(object, JSON_MAIN_KEY);
544     if (!cJSON_IsArray(array)) {
545         return false;
546     }
547 
548     cJSON *item = nullptr;
549     cJSON_ArrayForEach(item, array) {
550         if (!cJSON_IsString(item)) {
551             return false;
552         }
553         if ((item->valuestring != nullptr) && strcmp(bundleName, item->valuestring) == 0) {
554             return true;
555         }
556     }
557     return false;
558 }
559 
QueryBundleInfo(const char * bundleName)560 BundleInfo *ManagerService::QueryBundleInfo(const char *bundleName)
561 {
562     if (bundleMap_ == nullptr || bundleName == nullptr) {
563         return nullptr;
564     }
565     return bundleMap_->Get(bundleName);
566 }
567 
RemoveBundleInfo(const char * bundleName)568 void ManagerService::RemoveBundleInfo(const char *bundleName)
569 {
570     if (bundleMap_ == nullptr || bundleName == nullptr) {
571         return;
572     }
573     bundleMap_->Erase(bundleName);
574 }
575 
AddBundleInfo(BundleInfo * info)576 void ManagerService::AddBundleInfo(BundleInfo *info)
577 {
578     if (info == nullptr || info->bundleName == nullptr || bundleMap_ == nullptr) {
579         return;
580     }
581     bundleMap_->Add(info);
582 }
583 
UpdateBundleInfo(BundleInfo * info)584 bool ManagerService::UpdateBundleInfo(BundleInfo *info)
585 {
586     if (info == nullptr || info->bundleName == nullptr || bundleMap_ == nullptr) {
587         return false;
588     }
589     return bundleMap_->Update(info);
590 }
591 
GetBundleInfo(const char * bundleName,int32_t flags,BundleInfo & bundleInfo)592 uint8_t ManagerService::GetBundleInfo(const char *bundleName, int32_t flags, BundleInfo &bundleInfo)
593 {
594     if (bundleName == nullptr || bundleMap_ == nullptr) {
595         return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
596     }
597     return bundleMap_->GetBundleInfo(bundleName, flags, bundleInfo);
598 }
599 
HasSystemCapability(const char * sysCapName)600 bool ManagerService::HasSystemCapability(const char *sysCapName)
601 {
602     if (sysCapName == nullptr) {
603         return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
604     }
605     return SAMGR_GetInstance()->HasSystemCapability(sysCapName);
606 }
607 
GetSystemAvailableCapabilities(char syscap[][MAX_SYSCAP_NAME_LEN],int32_t * len)608 uint8_t ManagerService::GetSystemAvailableCapabilities(char syscap[][MAX_SYSCAP_NAME_LEN], int32_t *len)
609 {
610     if (syscap == nullptr || len == nullptr) {
611         return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
612     }
613     int32_t res = SAMGR_GetInstance()->GetSystemAvailableCapabilities(syscap, len);
614     if (res != ERR_OK) {
615         return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
616     }
617     return ERR_OK;
618 }
619 
GetBundleInfos(int32_t flags,BundleInfo ** bundleInfos,int32_t * len)620 uint8_t ManagerService::GetBundleInfos(int32_t flags, BundleInfo **bundleInfos, int32_t *len)
621 {
622     if (bundleMap_ == nullptr) {
623         return ERR_APPEXECFWK_OBJECT_NULL;
624     }
625     return bundleMap_->GetBundleInfos(flags, bundleInfos, len);
626 }
627 
GetBundleSize(const char * bundleName)628 uint32_t ManagerService::GetBundleSize(const char *bundleName)
629 {
630     if (bundleName == nullptr) {
631         return 0;
632     }
633     BundleInfo *installedInfo = bundleMap_->Get(bundleName);
634     if (installedInfo == nullptr) {
635         return 0;
636     }
637     char *codePath = installedInfo->codePath;
638     uint32_t codeBundleSize = BundleUtil::GetFileFolderSize(codePath);
639     if (codeBundleSize == 0) {
640         return 0;
641     }
642     char *dataPath = installedInfo->dataPath;
643     uint32_t dataBundleSize = BundleUtil::GetFileFolderSize(dataPath);
644     HILOG_INFO(HILOG_MODULE_APP, "bundle size is %{public}d\n", codeBundleSize + dataBundleSize);
645     return codeBundleSize + dataBundleSize;
646 }
647 
GetCodeDirPath() const648 std::string ManagerService::GetCodeDirPath() const
649 {
650     if (installer_ == nullptr) {
651         return "";
652     }
653     return installer_->GetCodeDirPath();
654 }
655 
GetDataDirPath() const656 std::string ManagerService::GetDataDirPath() const
657 {
658     if (installer_ == nullptr) {
659         return "";
660     }
661     return installer_->GetDataDirPath();
662 }
663 
GenerateInnerUid(std::map<int,std::string> & innerMap,const std::string & bundleName,int8_t bundleStyle,int32_t baseUid)664 static int32_t GenerateInnerUid(std::map<int, std::string> &innerMap, const std::string &bundleName,
665     int8_t bundleStyle, int32_t baseUid)
666 {
667     if (innerMap.empty()) {
668         innerMap.emplace(0, bundleName);
669         return baseUid;
670     }
671     int32_t ret = 0;
672     for (int32_t i = 0; i < innerMap.rbegin()->first; ++i) {
673         auto res = innerMap.emplace(i, bundleName);
674         if (res.second) {
675             return i + baseUid;
676         }
677     }
678 
679     if ((bundleStyle == SYSTEM_APP_FLAG) && (innerMap.rbegin()->first == BASE_SYS_VEN_UID - 1)) {
680         return INVALID_UID;
681     }
682 
683     if ((bundleStyle == THIRD_SYSTEM_APP_FLAG) && (innerMap.rbegin()->first == MAX_SYS_VEN_UID)) {
684         return INVALID_UID;
685     }
686     innerMap.emplace((innerMap.rbegin()->first + 1), bundleName);
687     ret = innerMap.rbegin()->first + baseUid;
688     return ret;
689 }
690 
GenerateUid(const char * bundleName,int8_t bundleStyle)691 int32_t ManagerService::GenerateUid(const char *bundleName, int8_t bundleStyle)
692 {
693     if (bundleName == nullptr) {
694         return INVALID_UID;
695     }
696 
697     if (bundleStyle == THIRD_SYSTEM_APP_FLAG) {
698         return GenerateInnerUid(sysVendorUidMap_, bundleName, THIRD_SYSTEM_APP_FLAG, BASE_SYS_VEN_UID);
699     } else if (bundleStyle == THIRD_APP_FLAG) {
700         return GenerateInnerUid(appUidMap_, bundleName, THIRD_APP_FLAG, BASE_APP_UID);
701     } else if (bundleStyle == SYSTEM_APP_FLAG) {
702         return GenerateInnerUid(sysUidMap_, bundleName, SYSTEM_APP_FLAG, BASE_SYS_UID);
703     } else {
704         return INVALID_UID;
705     }
706 }
707 
RecycleInnerUid(const std::string & bundleName,std::map<int,std::string> & innerMap)708 bool ManagerService::RecycleInnerUid(const std::string &bundleName, std::map<int, std::string> &innerMap)
709 {
710     auto it = innerMap.begin();
711     while (it != innerMap.end()) {
712         if (it->second == bundleName) {
713             innerMap.erase(it);
714             return true;
715         }
716         it++;
717     }
718     return false;
719 }
720 
RecycleUid(const char * bundleName)721 void ManagerService::RecycleUid(const char *bundleName)
722 {
723     if (bundleName == nullptr) {
724         return;
725     }
726 
727     if (RecycleInnerUid(bundleName, appUidMap_) || RecycleInnerUid(bundleName, sysVendorUidMap_) ||
728         RecycleInnerUid(bundleName, sysUidMap_)) {
729         return;
730     }
731 }
732 
ScanSharedLibPath()733 void ManagerService::ScanSharedLibPath()
734 {
735     BundleInfo *bundleInfos = nullptr;
736     int32_t len = 0;
737     if (bundleMap_->GetBundleInfos(1, &bundleInfos, &len) != ERR_OK) {
738         HILOG_ERROR(HILOG_MODULE_APP, "ScanSharedLibPath GetBundleInfos is error");
739         return;
740     }
741     if (bundleInfos == nullptr) {
742         HILOG_ERROR(HILOG_MODULE_APP, "ScanSharedLibPath bundleInfos is unavailable");
743         return;
744     }
745     for (int32_t index = 0; index < len; ++index) {
746         if (!(bundleInfos + index)->isSystemApp) {
747             continue;
748         }
749         std::string path = (bundleInfos + index)->codePath;
750         path = path + PATH_SEPARATOR + (bundleInfos + index)->moduleInfos[0].moduleName + PATH_SEPARATOR +
751                SHARED_LIB_NAME;
752         if (!BundleUtil::IsDir(path.c_str())) {
753             continue;
754         }
755 
756         if (BundleDaemonClient::GetInstance().MoveFile(path.c_str(), SHARED_LIB_PATH) != EC_SUCCESS) {
757             HILOG_WARN(HILOG_MODULE_APP, "ScanSharedLibPath move file to share library failed");
758         }
759     }
760     BundleInfoUtils::FreeBundleInfos(bundleInfos, len);
761 }
762 
RestoreUidAndGidMap()763 void ManagerService::RestoreUidAndGidMap()
764 {
765     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
766     cJSON *object = BundleUtil::GetJsonStream(uidJsonPath.c_str());
767     if (object == nullptr) {
768         return;
769     }
770 
771     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, "uid_and_gid");
772     if (!(cJSON_IsArray(uids))) {
773         cJSON_Delete(object);
774         return;
775     }
776     cJSON *uid = nullptr;
777     cJSON_ArrayForEach(uid, uids) {
778         cJSON *innerUid = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_UID);
779         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_PACKAGE);
780         if ((!cJSON_IsNumber(innerUid)) || (!cJSON_IsString(innerBundleName))) {
781             continue;
782         }
783         uint32_t uidValue = innerUid->valueint;
784         if ((uidValue < BASE_SYS_VEN_UID) && (uidValue >= BASE_SYS_UID)) {
785             sysUidMap_[uidValue - BASE_SYS_UID] = innerBundleName->valuestring;
786         } else if ((uidValue >= BASE_SYS_VEN_UID) && (uidValue <= MAX_SYS_VEN_UID)) {
787             sysVendorUidMap_[uidValue - BASE_SYS_VEN_UID] = innerBundleName->valuestring;
788         } else if (uidValue > MAX_SYS_VEN_UID) {
789             appUidMap_[uidValue - BASE_APP_UID] = innerBundleName->valuestring;
790         } else {
791             continue;
792         }
793     }
794     cJSON_Delete(object);
795     return;
796 }
797 } // namespace OHOS
798