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