Reduce db connection while installer backend is running
[platform/core/appfw/app-installers.git] / src / common / step / pkgmgr / step_check_installable.cc
1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/pkgmgr/step_check_installable.h"
6
7 #include <pkgmgr-info.h>
8 #include <sys/types.h>
9 #include <tzplatform_config.h>
10
11 #include <string>
12 #include <vector>
13
14 #include "common/utils/glist_range.h"
15 #include "common/utils/user_util.h"
16
17 namespace {
18
19 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
20
21 }  // namespace
22
23 namespace common_installer {
24 namespace pkgmgr {
25
26 Step::Status StepCheckInstallable::process() {
27   switch (context_->request_mode.get()) {
28     case RequestMode::USER: {
29       if (context_->pkg_query->IsGlobalPackage()) {
30         LOG(ERROR) << "This package is already installed as global package";
31         return Status::OPERATION_NOT_ALLOWED;
32       }
33       break;
34     }
35     case RequestMode::GLOBAL: {
36       UserList list = GetUserList();
37       for (auto l : list) {
38         uid_t uid = std::get<0>(l);
39         PkgQueryInterface pkg_query(context_->pkgid.get(), uid);
40         if (pkg_query.IsPackageInstalled(RequestMode::USER)) {
41           LOG(ERROR) << "This package is already installed by user("
42                      << uid << ")";
43           return Status::OPERATION_NOT_ALLOWED;
44         }
45       }
46       break;
47     }
48   }
49
50   std::vector<std::string> missing_pkgs;
51   manifest_x* manifest = context_->manifest_data.get();
52   for (const auto& dep : GListRange<dependency_x*>(manifest->dependencies)) {
53     // check only requires pkgs
54     if (strcmp(dep->type, "requires"))
55       continue;
56     PkgQueryInterface pkg_query(dep->depends_on, context_->uid.get());
57     if (!pkg_query.IsPackageInstalled(context_->request_mode.get()))
58       missing_pkgs.emplace_back(dep->depends_on);
59   }
60   if (missing_pkgs.size()) {
61     for (const auto& missing_pkg : missing_pkgs)
62       LOG(ERROR) << missing_pkg << " is required but not installed!";
63     return Status::OPERATION_NOT_ALLOWED;
64   }
65
66   return Status::OK;
67 }
68
69 Step::Status StepCheckInstallable::precheck() {
70   if (context_->pkgid.get().empty())
71     return Status::INVALID_VALUE;
72   return Status::OK;
73 }
74
75 }  // namespace pkgmgr
76 }  // namespace common_installer