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