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