• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "liteipc_adapter.h"
43 #include "log.h"
44 #include "samgr_lite.h"
45 #include "utils.h"
46 #include "want.h"
47 
48 namespace OHOS {
ManagerService()49 ManagerService::ManagerService()
50 {
51     installer_ = new BundleInstaller(INSTALL_PATH, DATA_PATH);
52     bundleMap_ = BundleMap::GetInstance();
53 }
54 
~ManagerService()55 ManagerService::~ManagerService()
56 {
57     if (installer_ != nullptr) {
58         delete installer_;
59         installer_ = nullptr;
60     }
61     sysUidMap_.clear();
62     sysVendorUidMap_.clear();
63     appUidMap_.clear();
64 }
65 
InnerTransact(uint32_t code,uint8_t resultCode,const char * bundleName)66 static void InnerTransact(uint32_t code, uint8_t resultCode, const char *bundleName)
67 {
68     if (bundleName == nullptr) {
69         return;
70     }
71     IpcIo io;
72     char data[IPC_IO_DATA_MAX];
73     IpcIo reply;
74     uintptr_t ptr;
75     IpcIoInit(&io, data, IPC_IO_DATA_MAX, 0);
76     IpcIoPushInt32(&io, static_cast<int32_t>(resultCode));
77     IpcIoPushString(&io, bundleName);
78     if (!IpcIoAvailable(&io)) {
79         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS InnerTransact ipc failed");
80         return;
81     }
82     std::vector<SvcIdentity> svcIdentity = ManagerService::GetInstance().GetServiceId();
83     if (svcIdentity.empty()) {
84         return;
85     }
86     for (const auto& svc : svcIdentity) {
87         int32_t ret = Transact(NULL, svc, code, &io, &reply, LITEIPC_FLAG_ONEWAY, &ptr);
88         if (ret != LITEIPC_OK) {
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[IPC_IO_DATA_MAX];
99     IpcIo reply;
100     IpcIoInit(&io, data, IPC_IO_DATA_MAX, 0);
101     IpcIoPushInt32(&io, static_cast<int32_t>(resultCode));
102     int32_t ret = Transact(NULL, svc, code, &io, &reply, LITEIPC_FLAG_ONEWAY, NULL);
103     if (ret != LITEIPC_OK) {
104         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS InnerSelfTransact failed %{public}d\n", ret);
105     }
106 #ifdef __LINUX__
107     BinderRelease(svc.ipcContext, svc.handle);
108 #endif
109 }
110 
GetServiceId() const111 std::vector<SvcIdentity> ManagerService::GetServiceId() const
112 {
113     return svcIdentity_;
114 }
115 
GetAmsInterface(AmsInnerInterface ** amsInterface)116 bool ManagerService::GetAmsInterface(AmsInnerInterface **amsInterface)
117 {
118     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE);
119     if (iUnknown == NULL) {
120         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS GetAmsInterface failed");
121         return false;
122     }
123 
124     int result = iUnknown->QueryInterface(iUnknown, 0, (void **) amsInterface);
125     if (result != 0) {
126         HILOG_ERROR(HILOG_MODULE_APP, "BundleMS Query ams Interface failed: %{public}d\n", result);
127         return false;
128     }
129 
130     return true;
131 }
132 
SetExternalInstallMode(bool enable)133 uint8_t ManagerService::SetExternalInstallMode(bool enable)
134 {
135     IsExternalInstallMode_ = enable;
136     HILOG_INFO(HILOG_MODULE_APP, "current install mode is %d", IsExternalInstallMode_);
137     return ERR_OK;
138 }
139 
IsExternalInstallMode() const140 bool ManagerService::IsExternalInstallMode() const
141 {
142     return IsExternalInstallMode_;
143 }
144 
SetDebugMode(bool enable)145 uint8_t ManagerService::SetDebugMode(bool enable)
146 {
147     int32_t ret = APPVERI_SetDebugMode(enable);
148     if (ret < 0) {
149         HILOG_ERROR(HILOG_MODULE_APP, "set signature debug mode failed");
150         return ERR_APPEXECFWK_SET_DEBUG_MODE_ERROR;
151     }
152     isDebugMode_ = enable;
153     HILOG_INFO(HILOG_MODULE_APP, "current sign debug mode is %d", isDebugMode_);
154     return ERR_OK;
155 }
156 
IsDebugMode() const157 bool ManagerService::IsDebugMode() const
158 {
159     return isDebugMode_;
160 }
161 
162 #ifdef OHOS_DEBUG
SetSignMode(bool enable)163 uint8_t ManagerService::SetSignMode(bool enable)
164 {
165     isSignMode_ = enable;
166     HILOG_INFO(HILOG_MODULE_APP, "current sign mode is %d", isSignMode_);
167     return ERR_OK;
168 }
169 
IsSignMode() const170 bool ManagerService::IsSignMode() const
171 {
172     return isSignMode_;
173 }
174 #endif
175 
ServiceMsgProcess(Request * request)176 void ManagerService::ServiceMsgProcess(Request* request)
177 {
178     if (request == nullptr) {
179         return;
180     }
181 
182     if (installer_ == nullptr) {
183         installer_ = new BundleInstaller(INSTALL_PATH, DATA_PATH);
184     }
185 
186     switch (request->msgId) {
187         case BUNDLE_SERVICE_INITED: {
188             if (!BundleDaemonClient::GetInstance().Initialize()) {
189                 HILOG_ERROR(HILOG_MODULE_APP, "BundleDeamonClient initialize fail");
190                 return;
191             }
192             ScanPackages();
193             ScanSharedLibPath();
194             AmsInnerInterface *amsInterface = nullptr;
195             if (!GetAmsInterface(&amsInterface)) {
196                 return;
197             }
198             if (amsInterface != nullptr) {
199                 amsInterface->StartKeepAliveApps();
200             }
201             break;
202         }
203         case BUNDLE_UPDATED:
204             /* Process update request by Install() */
205         case BUNDLE_INSTALLED: {
206             auto info = reinterpret_cast<SvcIdentityInfo *>(request->data);
207             if (info == nullptr) {
208                 return;
209             }
210             if (info->svc == nullptr || info->path == nullptr) {
211                 AdapterFree(info->path);
212                 AdapterFree(info->svc);
213                 return;
214             }
215 
216             InstallThirdBundle(info->path, *(info->svc), info->installLocation);
217             AdapterFree(info->path);
218             AdapterFree(info->svc);
219             break;
220         }
221         case BUNDLE_UNINSTALLED: {
222             auto info = reinterpret_cast<SvcIdentityInfo *>(request->data);
223             if (info == nullptr) {
224                 return;
225             }
226             if ((info->bundleName == nullptr) || (info->svc == nullptr)) {
227                 AdapterFree(info->bundleName);
228                 AdapterFree(info->svc);
229                 return;
230             }
231 
232             InstallParam installParam = {.installLocation = 1, .keepData = info->keepData};
233             uint8_t bResult = installer_->Uninstall(info->bundleName, installParam);
234             InnerSelfTransact(UNINSTALL_CALLBACK, bResult, *(info->svc));
235             InnerTransact(UNINSTALL_CALLBACK, bResult, info->bundleName);
236             if (bResult == ERR_OK) {
237                 RecycleUid(info->bundleName);
238             }
239             AdapterFree(info->bundleName);
240             AdapterFree(info->svc);
241             break;
242         }
243         case BUNDLE_CHANGE_CALLBACK: {
244             auto svc = reinterpret_cast<SvcIdentity *>(request->data);
245             if (svc == nullptr) {
246                 return;
247             }
248             if (request->msgValue) {
249                 AddCallbackServiceId(*svc);
250             } else {
251                 RemoveCallbackServiceId(*svc);
252             }
253             break;
254         }
255         default: {
256             break;
257         }
258     }
259 }
260 
CompareServiceId(const SvcIdentity & svc1,const SvcIdentity & svc2)261 static bool CompareServiceId(const SvcIdentity &svc1, const SvcIdentity &svc2)
262 {
263     return (svc1.handle == svc2.handle) && (svc1.token == svc2.token);
264 }
265 
AddCallbackServiceId(const SvcIdentity & svc)266 void ManagerService::AddCallbackServiceId(const SvcIdentity &svc)
267 {
268     for (auto it = svcIdentity_.begin(); it != svcIdentity_.end(); ++it) {
269         if (CompareServiceId(*it, svc)) {
270             return;
271         }
272     }
273     svcIdentity_.emplace_back(svc);
274 }
275 
RemoveCallbackServiceId(const SvcIdentity & svc)276 void ManagerService::RemoveCallbackServiceId(const SvcIdentity &svc)
277 {
278 #ifdef __LINUX__
279     BinderRelease(svc.ipcContext, svc.handle);
280 #endif
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     std::string codeDirPath;
651     if (installer_ == nullptr) {
652         return codeDirPath;
653     }
654     return installer_->GetCodeDirPath();
655 }
656 
GetDataDirPath() const657 std::string ManagerService::GetDataDirPath() const
658 {
659     std::string dataDirPath;
660     if (installer_ == nullptr) {
661         return dataDirPath;
662     }
663     return installer_->GetDataDirPath();
664 }
665 
GenerateInnerUid(std::map<int,std::string> & innerMap,const std::string & bundleName,int8_t bundleStyle,int32_t baseUid)666 static int32_t GenerateInnerUid(std::map<int, std::string> &innerMap, const std::string &bundleName,
667     int8_t bundleStyle, int32_t baseUid)
668 {
669     if (innerMap.empty()) {
670         innerMap.emplace(0, bundleName);
671         return baseUid;
672     }
673     int32_t ret = 0;
674     for (int32_t i = 0; i < innerMap.rbegin()->first; ++i) {
675         if (innerMap.find(i) == innerMap.end()) {
676             innerMap.emplace(i, bundleName);
677             ret = i + baseUid;
678             return ret;
679         }
680     }
681 
682     if ((bundleStyle == SYSTEM_APP_FLAG) && (innerMap.rbegin()->first == BASE_SYS_VEN_UID - 1)) {
683         return INVALID_UID;
684     }
685 
686     if ((bundleStyle == THIRD_SYSTEM_APP_FLAG) && (innerMap.rbegin()->first == MAX_SYS_VEN_UID)) {
687         return INVALID_UID;
688     }
689     innerMap.emplace((innerMap.rbegin()->first + 1), bundleName);
690     ret = innerMap.rbegin()->first + baseUid;
691     return ret;
692 }
693 
GenerateUid(const char * bundleName,int8_t bundleStyle)694 int32_t ManagerService::GenerateUid(const char *bundleName, int8_t bundleStyle)
695 {
696     if (bundleName == nullptr) {
697         return INVALID_UID;
698     }
699 
700     if (bundleStyle == THIRD_SYSTEM_APP_FLAG) {
701         return GenerateInnerUid(sysVendorUidMap_, bundleName, THIRD_SYSTEM_APP_FLAG, BASE_SYS_VEN_UID);
702     } else if (bundleStyle == THIRD_APP_FLAG) {
703         return GenerateInnerUid(appUidMap_, bundleName, THIRD_APP_FLAG, BASE_APP_UID);
704     } else if (bundleStyle == SYSTEM_APP_FLAG) {
705         return GenerateInnerUid(sysUidMap_, bundleName, SYSTEM_APP_FLAG, BASE_SYS_UID);
706     } else {
707         return INVALID_UID;
708     }
709 }
710 
RecycleInnerUid(const std::string & bundleName,std::map<int,std::string> & innerMap)711 bool ManagerService::RecycleInnerUid(const std::string &bundleName, std::map<int, std::string> &innerMap)
712 {
713     auto it = innerMap.begin();
714     while (it != innerMap.end()) {
715         if (it->second == bundleName) {
716             innerMap.erase(it);
717             return true;
718         }
719         it++;
720     }
721     return false;
722 }
723 
RecycleUid(const char * bundleName)724 void ManagerService::RecycleUid(const char *bundleName)
725 {
726     if (bundleName == nullptr) {
727         return;
728     }
729 
730     if (RecycleInnerUid(bundleName, appUidMap_) || RecycleInnerUid(bundleName, sysVendorUidMap_) ||
731         RecycleInnerUid(bundleName, sysUidMap_)) {
732         return;
733     }
734 }
735 
ScanSharedLibPath()736 void ManagerService::ScanSharedLibPath()
737 {
738     BundleInfo *bundleInfos = nullptr;
739     int32_t len = 0;
740     if (bundleMap_->GetBundleInfos(1, &bundleInfos, &len) != ERR_OK) {
741         HILOG_ERROR(HILOG_MODULE_APP, "ScanSharedLibPath GetBundleInfos is error");
742         return;
743     }
744     if (bundleInfos == nullptr) {
745         HILOG_ERROR(HILOG_MODULE_APP, "ScanSharedLibPath bundleInfos is unavailable");
746         return;
747     }
748     for (int32_t index = 0; index < len; ++index) {
749         if (!(bundleInfos + index)->isSystemApp) {
750             continue;
751         }
752         std::string path = (bundleInfos + index)->codePath;
753         path = path + PATH_SEPARATOR + (bundleInfos + index)->moduleInfos[0].moduleName + PATH_SEPARATOR +
754                SHARED_LIB_NAME;
755         if (!BundleUtil::IsDir(path.c_str())) {
756             continue;
757         }
758 
759         if (BundleDaemonClient::GetInstance().MoveFile(path.c_str(), SHARED_LIB_PATH) != EC_SUCCESS) {
760             HILOG_WARN(HILOG_MODULE_APP, "ScanSharedLibPath move file to share library failed");
761         }
762     }
763     BundleInfoUtils::FreeBundleInfos(bundleInfos, len);
764 }
765 
RestoreUidAndGidMap()766 void ManagerService::RestoreUidAndGidMap()
767 {
768     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
769     cJSON *object = BundleUtil::GetJsonStream(uidJsonPath.c_str());
770     if (object == nullptr) {
771         return;
772     }
773 
774     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, "uid_and_gid");
775     if (!(cJSON_IsArray(uids))) {
776         cJSON_Delete(object);
777         return;
778     }
779     cJSON *uid = nullptr;
780     cJSON_ArrayForEach(uid, uids) {
781         cJSON *innerUid = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_UID);
782         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_PACKAGE);
783         if ((!cJSON_IsNumber(innerUid)) || (!cJSON_IsString(innerBundleName))) {
784             continue;
785         }
786         uint32_t uidValue = innerUid->valueint;
787         if ((uidValue < BASE_SYS_VEN_UID) && (uidValue >= BASE_SYS_UID)) {
788             sysUidMap_[uidValue - BASE_SYS_UID] = innerBundleName->valuestring;
789         } else if ((uidValue >= BASE_SYS_VEN_UID) && (uidValue <= MAX_SYS_VEN_UID)) {
790             sysVendorUidMap_[uidValue - BASE_SYS_VEN_UID] = innerBundleName->valuestring;
791         } else if (uidValue > MAX_SYS_VEN_UID) {
792             appUidMap_[uidValue - BASE_APP_UID] = innerBundleName->valuestring;
793         } else {
794             continue;
795         }
796     }
797     cJSON_Delete(object);
798     return;
799 }
800 } // namespace OHOS
801