Fix build error
[platform/core/appfw/pkgmgr-info.git] / src / common / database / db_handle_provider.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 <sys/types.h>
18
19 #include <tzplatform_config.h>
20
21 #include "db_handle_provider.hh"
22 #include "pkgmgr-info.h"
23 #include "pkgmgrinfo_debug.h"
24
25 #include <algorithm>
26 #include <vector>
27
28 #ifdef LOG_TAG
29 #undef LOG_TAG
30 #endif
31 #define LOG_TAG "PKGMGR_INFO"
32
33 namespace {
34
35 constexpr uid_t REGULAR_USER = 5000;
36
37 uid_t GetGlobalUID() {
38   return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
39 }
40
41 bool IsUserRequest(uid_t uid) {
42   return (uid > REGULAR_USER);
43 }
44
45 uid_t ConvertUID(uid_t uid) {
46   if (uid < REGULAR_USER)
47     return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
48   else
49     return uid;
50 }
51
52 }  // namespace
53
54 namespace pkgmgr_common {
55
56 std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>>
57     DBHandleProvider::provider_;
58 bool DBHandleProvider::is_memory_ = false;
59 std::vector<pid_t> DBHandleProvider::pid_list_;
60
61 DBHandleProvider::DBHandleProvider(uid_t uid) : uid_(uid),
62     global_parser_memory_db_handle_(nullptr, sqlite3_close_v2),
63     parser_memory_db_handle_(nullptr, sqlite3_close_v2),
64     cert_memory_db_handle_(nullptr, sqlite3_close_v2) {
65   char *tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
66   global_parser_file_db_path_ = tmp_path;
67   free(tmp_path);
68
69   tmp_path = getUserPkgParserDBPathUID(uid_);
70   parser_file_db_path_ = tmp_path;
71   free(tmp_path);
72
73   tmp_path = getUserPkgCertDBPath();
74   cert_file_db_path_ = tmp_path;
75   free(tmp_path);
76
77   global_parser_memory_db_path_ = "file:parserdb?mode=memory&cache=shared";
78   parser_memory_db_path_ = "file:parserdb" +
79       std::to_string(static_cast<int>(uid_)) + "?mode=memory&cache=shared";
80   cert_memory_db_path_ = "file:certdb" +
81       std::to_string(static_cast<int>(uid_)) + "?mode=memory&cache=shared";
82 }
83
84 DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) {
85   static std::mutex singleton_lock;
86   std::unique_lock<std::mutex> u(singleton_lock);
87   uid = ConvertUID(uid);
88   auto& prov = provider_[uid];
89   if (prov == nullptr) {
90     prov.reset(new DBHandleProvider(uid));
91   }
92
93   return *prov;
94 }
95
96 std::vector<std::string> DBHandleProvider::GetParserDBPath(pid_t pid) {
97   std::unique_lock<std::mutex> u(lock_);
98   std::vector<std::string> db_path_list;
99   bool tmp_is_memory = is_memory_;
100
101   if (tmp_is_memory) {
102     std::vector<pid_t>::iterator it = std::find(pid_list_.begin(),
103         pid_list_.end(), pid);
104     if (it != pid_list_.end())
105       tmp_is_memory = false;
106   }
107
108
109   if (tmp_is_memory) {
110     db_path_list.emplace_back(parser_memory_db_path_);
111     if (IsUserRequest(uid_))
112       db_path_list.emplace_back(global_parser_memory_db_path_);
113   } else {
114     db_path_list.emplace_back(parser_file_db_path_);
115     if (IsUserRequest(uid_))
116       db_path_list.emplace_back(global_parser_file_db_path_);
117   }
118   return db_path_list;
119 }
120
121 std::string DBHandleProvider::GetCertDBPath(pid_t pid) {
122   std::unique_lock<std::mutex> u(lock_);
123   bool tmp_is_memory = is_memory_;
124
125   if (tmp_is_memory) {
126     std::vector<pid_t>::iterator it = std::find(pid_list_.begin(),
127         pid_list_.end(), pid);
128     if (it != pid_list_.end())
129       tmp_is_memory = false;
130   }
131
132   if (tmp_is_memory)
133     return cert_memory_db_path_;
134   else
135     return cert_file_db_path_;
136 }
137
138 sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
139     const std::string& memorydb_path) {
140   sqlite3* memorydb = nullptr;
141   sqlite3* filedb = nullptr;
142   int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
143       SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr);
144   if (ret != SQLITE_OK) {
145     LOGE("Failed to open memory DB %d(%s)", ret, memorydb_path.c_str());
146     return nullptr;
147   }
148
149   ret = sqlite3_open_v2(filedb_path.c_str(), &filedb,
150       SQLITE_OPEN_READONLY, nullptr);
151   if (ret != SQLITE_OK) {
152     LOGE("Failed to open file DB %d(%s)", ret, filedb_path.c_str());
153     sqlite3_close_v2(memorydb);
154     return nullptr;
155   }
156   sqlite3_backup* backup = sqlite3_backup_init(memorydb, "main",
157       filedb, "main");
158   if (backup == nullptr) {
159     LOGE("Failed to backup for memory DB");
160     sqlite3_close_v2(memorydb);
161     sqlite3_close_v2(filedb);
162     return nullptr;
163   }
164
165   sqlite3_backup_step(backup, -1);
166   sqlite3_backup_finish(backup);
167   LOGD("Set memory DB(%s)", memorydb_path.c_str());
168   sqlite3_close_v2(filedb);
169   return memorydb;
170 }
171
172 void DBHandleProvider::SetMemoryMode(pid_t pid, bool flag) {
173   std::unique_lock<std::mutex> u(lock_);
174   if (is_memory_ == flag)
175     return;
176
177   is_memory_ = flag;
178   if (is_memory_ == true) {
179     sqlite3* parser_db = GetMemoryDBHandle(parser_file_db_path_,
180         parser_memory_db_path_);
181     if (parser_db != nullptr)
182       parser_memory_db_handle_.reset(parser_db);
183     sqlite3* global_parser_file_db = GetMemoryDBHandle(global_parser_file_db_path_,
184         global_parser_memory_db_path_);
185     if (global_parser_file_db)
186       global_parser_memory_db_handle_.reset(global_parser_file_db);
187     sqlite3* cert_db = GetMemoryDBHandle(cert_file_db_path_,
188         cert_memory_db_path_);
189     if (cert_db != nullptr)
190       cert_memory_db_handle_.reset(cert_db);
191     std::vector<pid_t>::iterator it =
192         std::find(pid_list_.begin(), pid_list_.end(), pid);
193
194     if (it == pid_list_.end())
195       pid_list_.emplace_back(pid);
196   } else {
197     parser_memory_db_handle_.reset(nullptr);
198     cert_memory_db_handle_.reset(nullptr);
199     global_parser_memory_db_handle_.reset(nullptr);
200     std::vector<pid_t>::iterator it =
201         std::find(pid_list_.begin(), pid_list_.end(), pid);
202     if (it != pid_list_.end())
203       pid_list_.erase(it);
204     else
205       LOGE("Given pid is not exists in pid list : %d", pid);
206   }
207
208   LOGD("Set Memory mode : %s", flag ? "Memory" : "File");
209 }
210
211 }  // namespace pkgmgr_common