Refactor pkgmgr-info
[platform/core/appfw/pkgmgr-info.git] / src / server / database / appinfo_db_handler.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "appinfo_db_handler.hh"
18
19 #include <shared_mutex>
20 #include <vector>
21
22 #include "cache_flag.hh"
23 #include "db_handle_provider.hh"
24 #include "utils/logging.hh"
25
26 #include "pkgmgrinfo_basic.h"
27 #include "pkgmgrinfo_internal.h"
28
29 namespace {
30
31 uid_t globaluser_uid = -1;
32
33 uid_t GetGlobalUID() {
34   if (globaluser_uid == (uid_t)-1)
35     globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
36
37   return globaluser_uid;
38 }
39
40 }  // namespace
41
42 namespace pkgmgr_server {
43 namespace database {
44
45 AppInfoDBHandler::AppInfoDBHandler(uid_t uid, int pid)
46     : AbstractDBHandler(uid, pid), filter_(nullptr), uid_(uid) {}
47
48 AppInfoDBHandler::~AppInfoDBHandler() {}
49
50 std::vector<std::shared_ptr<application_x>> AppInfoDBHandler::DetachAppHandle() {
51   return std::move(handle_list_);
52 }
53
54 void AppInfoDBHandler::SetFilter(pkgmgrinfo_filter_x* filter) {
55   filter_ = filter;
56 }
57
58 int AppInfoDBHandler::GetHandleFromDB() {
59   if (!Connect()) {
60     LOG(ERROR) << "Failed to connect database";
61     return PMINFO_R_ERROR;
62   }
63
64   const auto& conn_list = GetConnection();
65   std::vector<std::shared_ptr<application_x>> list;
66   int ret = PMINFO_R_OK;
67   for (const auto& [db, uid] : conn_list) {
68     ret = internal::GetAppInfo(db, filter_, uid, uid_, GetLocale(), list);
69     if (ret == PMINFO_R_ERROR) {
70       LOG(DEBUG) << "Failed to GetAppInfo: " << ret;
71       break;
72     }
73   }
74
75   if (list.empty())
76     ret = PMINFO_R_ENOENT;
77
78   if (ret == PMINFO_R_OK)
79     handle_list_ = std::move(list);
80
81   return ret;
82 }
83
84 void AppInfoDBHandler::GetApplicationFromCache(uid_t uid,
85     const std::string& application) {
86   std::vector<std::shared_ptr<application_x>> app_list;
87   app_list = DBHandleProvider::GetInst(uid).GetApplications(GetPID(),
88       filter_, application);
89
90   handle_list_.reserve(app_list.size() + handle_list_.size());
91   std::move(std::begin(app_list), std::end(app_list),
92             std::back_inserter(handle_list_));
93 }
94
95 int AppInfoDBHandler::GetHandleFromCache() {
96   std::string application;
97
98   for (auto* it = filter_->list; it != nullptr; it = g_slist_next(it)) {
99     auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
100     if (node->prop == E_PMINFO_APPINFO_PROP_APP_ID) {
101       application = node->value;
102       break;
103     }
104   }
105
106   if (uid_ > REGULAR_USER)
107     GetApplicationFromCache(uid_, application);
108
109   GetApplicationFromCache(GetGlobalUID(), application);
110
111   if (handle_list_.empty())
112     return PMINFO_R_ENOENT;
113
114   return PMINFO_R_OK;
115 }
116
117 int AppInfoDBHandler::Execute() {
118   std::shared_lock<std::shared_mutex> s(lock_);
119   SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
120   SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
121
122   if (DBHandleProvider::IsWriter(GetPID()))
123     return GetHandleFromDB();
124
125   if (uid_ <= GetDefaultUser() &&
126       CacheFlag::GetStatus() == CacheFlag::Status::PREPARED) {
127     auto cache_lock = CacheFlag::GetReaderLock();
128     if (cache_lock.try_lock() &&
129         CacheFlag::GetStatus() == CacheFlag::Status::PREPARED)
130       return GetHandleFromCache();
131   }
132
133   return GetHandleFromDB();
134 }
135
136 }  // namespace database
137 }  // namespace pkgmgr_server