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