Change pid related bahavior
[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 is_file_access = is_memory_;
100   std::vector<pid_t>::iterator it = std::find(pid_list_.begin(),
101       pid_list_.end(), pid);
102   if (it == pid_list_.end())
103     is_file_access = true;
104
105   if (!is_file_access) {
106     db_path_list.emplace_back(parser_memory_db_path_);
107     if (IsUserRequest(uid_))
108       db_path_list.emplace_back(global_parser_memory_db_path_);
109   } else {
110     db_path_list.emplace_back(parser_file_db_path_);
111     if (IsUserRequest(uid_))
112       db_path_list.emplace_back(global_parser_file_db_path_);
113   }
114   return db_path_list;
115 }
116
117 std::string DBHandleProvider::GetCertDBPath(pid_t pid) {
118   std::unique_lock<std::mutex> u(lock_);
119   bool is_file_access = is_memory_;
120   std::vector<pid_t>::iterator it = std::find(pid_list_.begin(),
121       pid_list_.end(), pid);
122   if (it == pid_list_.end())
123     is_file_access = true;
124
125   if (!is_file_access)
126     return cert_memory_db_path_;
127   else
128     return cert_file_db_path_;
129 }
130
131 sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
132     const std::string& memorydb_path) {
133   sqlite3* memorydb = nullptr;
134   sqlite3* filedb = nullptr;
135   int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb,
136       SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr);
137   if (ret != SQLITE_OK) {
138     LOGE("Failed to open memory DB %d(%s)", ret, memorydb_path.c_str());
139     return nullptr;
140   }
141
142   ret = sqlite3_open_v2(filedb_path.c_str(), &filedb,
143       SQLITE_OPEN_READONLY, nullptr);
144   if (ret != SQLITE_OK) {
145     LOGE("Failed to open file DB %d(%s)", ret, filedb_path.c_str());
146     sqlite3_close_v2(memorydb);
147     return nullptr;
148   }
149   sqlite3_backup* backup = sqlite3_backup_init(memorydb, "main",
150       filedb, "main");
151   if (backup == nullptr) {
152     LOGE("Failed to backup for memory DB");
153     sqlite3_close_v2(memorydb);
154     sqlite3_close_v2(filedb);
155     return nullptr;
156   }
157
158   sqlite3_backup_step(backup, -1);
159   sqlite3_backup_finish(backup);
160   LOGD("Set memory DB(%s)", memorydb_path.c_str());
161   sqlite3_close_v2(filedb);
162   return memorydb;
163 }
164
165 void DBHandleProvider::SetMemoryMode(pid_t pid, bool flag) {
166   std::unique_lock<std::mutex> u(lock_);
167   if (is_memory_ == flag)
168     return;
169
170   is_memory_ = flag;
171   if (is_memory_ == true) {
172     sqlite3* parser_db = GetMemoryDBHandle(parser_file_db_path_,
173         parser_memory_db_path_);
174     if (parser_db != nullptr)
175       parser_memory_db_handle_.reset(parser_db);
176     sqlite3* global_parser_file_db = GetMemoryDBHandle(global_parser_file_db_path_,
177         global_parser_memory_db_path_);
178     if (global_parser_file_db)
179       global_parser_memory_db_handle_.reset(global_parser_file_db);
180     sqlite3* cert_db = GetMemoryDBHandle(cert_file_db_path_,
181         cert_memory_db_path_);
182     if (cert_db != nullptr)
183       cert_memory_db_handle_.reset(cert_db);
184     std::vector<pid_t>::iterator it =
185         std::find(pid_list_.begin(), pid_list_.end(), pid);
186
187     if (it == pid_list_.end())
188       pid_list_.emplace_back(pid);
189   } else {
190     parser_memory_db_handle_.reset(nullptr);
191     cert_memory_db_handle_.reset(nullptr);
192     global_parser_memory_db_handle_.reset(nullptr);
193     std::vector<pid_t>::iterator it =
194         std::find(pid_list_.begin(), pid_list_.end(), pid);
195     if (it != pid_list_.end())
196       pid_list_.erase(it);
197     else
198       LOGE("Given pid is not exists in pid list : %d", pid);
199   }
200
201   LOGD("Set Memory mode : %s", flag ? "Memory" : "File");
202 }
203
204 }  // namespace pkgmgr_common