#include <fcntl.h>
#include <glib.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <tzplatform_config.h>
#include "pkgmgr-info.h"
#include "pkgmgrinfo_debug.h"
#include "pkgmgrinfo_internal.h"
+#include "pkgmgrinfo_internal.hh"
#include "pkgmgrinfo_private.h"
#ifdef LOG_TAG
return uid;
}
-static const std::string global_parser_memory_db_path =
+bool GetModifiedTime(const char* dbpath, timespec* t) {
+ if (dbpath == nullptr || t == nullptr) {
+ LOG(ERROR) << "Invalid argument";
+ return false;
+ }
+
+ struct stat attr;
+ if (stat(dbpath, &attr)) {
+ LOG(ERROR) << "Fail to get status from file "
+ << dbpath << " errno : " << errno;
+ return false;
+ }
+
+ *t = attr.st_mtim;
+
+ return true;
+}
+
+static const std::string global_parser_memdb_path =
"file:parserdb?mode=memory&cache=shared";
-static const std::string cert_memory_db_path =
+static const std::string cert_memdb_path =
"file:certdb?mode=memory&cache=shared";
} // namespace
namespace database {
std::unordered_map<uid_t, std::unique_ptr<DBHandleProvider>>
- DBHandleProvider::provider_;
-bool DBHandleProvider::is_memory_global_ = false;
+ DBHandleProvider::provider_map_;
+bool DBHandleProvider::is_global_memdb_set_ = false;
std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
- DBHandleProvider::global_parser_memory_db_handle_(nullptr,
- sqlite3_close_v2);
+ DBHandleProvider::global_parser_memdb_handle_(nullptr,
+ sqlite3_close_v2);
std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*>
- DBHandleProvider::cert_memory_db_handle_(nullptr, sqlite3_close_v2);
-std::string DBHandleProvider::global_parser_file_db_path_;
-std::string DBHandleProvider::cert_file_db_path_;
-std::unordered_set<pid_t> DBHandleProvider::pid_list_;
+ DBHandleProvider::cert_memdb_handle_(nullptr, sqlite3_close_v2);
+std::string DBHandleProvider::global_parser_filedb_path_;
+std::string DBHandleProvider::cert_filedb_path_;
+std::unordered_set<pid_t> DBHandleProvider::writer_pid_list_;
std::recursive_mutex DBHandleProvider::lock_;
-std::mutex DBHandleProvider::pid_list_lock_;
+std::shared_mutex DBHandleProvider::pid_list_lock_;
DBHandleProvider::DBHandleProvider(uid_t uid)
: uid_(uid),
- is_memory_(false),
- parser_memory_db_handle_(nullptr, sqlite3_close_v2) {
+ is_user_memdb_set_(false),
+ parser_memdb_handle_(nullptr, sqlite3_close_v2) {
char* tmp_path;
- if (global_parser_file_db_path_.empty()) {
+ if (global_parser_filedb_path_.empty()) {
tmp_path = getUserPkgParserDBPathUID(GetGlobalUID());
- global_parser_file_db_path_ = tmp_path;
+ global_parser_filedb_path_ = tmp_path;
free(tmp_path);
+ }
+ if (cert_filedb_path_.empty()) {
tmp_path = getUserPkgCertDBPath();
- cert_file_db_path_ = tmp_path;
+ cert_filedb_path_ = tmp_path;
free(tmp_path);
}
tmp_path = getUserPkgParserDBPathUID(uid_);
- parser_file_db_path_ = tmp_path;
+ user_parser_filedb_path_ = tmp_path;
free(tmp_path);
- parser_memory_db_path_ = "file:parserdb" +
- std::to_string(static_cast<int>(uid_)) +
- "?mode=memory&cache=shared";
+ user_parser_memdb_path_ = "file:parserdb" +
+ std::to_string(static_cast<int>(uid_)) +
+ "?mode=memory&cache=shared";
}
DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) {
- static std::mutex singleton_lock_;
- std::unique_lock<std::mutex> u(singleton_lock_);
+ static std::shared_mutex singleton_lock_;
+ std::shared_lock<std::shared_mutex> s(singleton_lock_);
uid = ConvertUID(uid);
- auto& prov = provider_[uid];
+ auto it = provider_map_.find(uid);
+ if (it != provider_map_.end())
+ return *(it->second);
+
+ s.unlock();
+ std::unique_lock<std::shared_mutex> u(singleton_lock_);
+ auto& prov = provider_map_[uid];
if (prov == nullptr)
prov.reset(new DBHandleProvider(uid));
}
bool DBHandleProvider::IsCrashedWriteRequest() {
- std::unique_lock<std::mutex> u(pid_list_lock_);
+ std::unique_lock<std::shared_mutex> u(pid_list_lock_);
- if (pid_list_.empty())
+ if (writer_pid_list_.empty())
return false;
bool ret = true;
- LOG(DEBUG) << "Check process count : " << pid_list_.size();
+ LOG(DEBUG) << "Check process count : " << writer_pid_list_.size();
std::vector<pid_t> remove_pids;
- for (pid_t pid : pid_list_) {
+ for (pid_t pid : writer_pid_list_) {
std::string status_path = "/proc/" + std::to_string(pid) + "/status";
int fd = open(status_path.c_str(), O_RDONLY);
}
for (pid_t pid : remove_pids)
- pid_list_.erase(pid);
+ writer_pid_list_.erase(pid);
return ret;
}
std::unique_lock<std::recursive_mutex> u(lock_);
std::vector<std::pair<std::string, uid_t>> db_path_list;
- if (is_memory_ != is_memory_global_)
- is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
+ if (is_user_memdb_set_ != is_global_memdb_set_)
+ is_global_memdb_set_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
if (IsMemoryDBActive(pid, write)) {
if (uid_ > REGULAR_USER)
- db_path_list.emplace_back(std::make_pair(parser_memory_db_path_, uid_));
+ db_path_list.emplace_back(std::make_pair(user_parser_memdb_path_, uid_));
+
db_path_list.emplace_back(
- std::make_pair(global_parser_memory_db_path, GetGlobalUID()));
+ std::make_pair(global_parser_memdb_path, GetGlobalUID()));
} else {
if (uid_ > REGULAR_USER)
- db_path_list.emplace_back(std::make_pair(parser_file_db_path_, uid_));
+ db_path_list.emplace_back(std::make_pair(user_parser_filedb_path_, uid_));
+
db_path_list.emplace_back(
- std::make_pair(global_parser_file_db_path_, GetGlobalUID()));
+ std::make_pair(global_parser_filedb_path_, GetGlobalUID()));
}
if (db_path_list.size() == 1) {
std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) {
std::unique_lock<std::recursive_mutex> u(lock_);
- if (is_memory_ != is_memory_global_)
- is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
+ if (is_user_memdb_set_ != is_global_memdb_set_)
+ is_global_memdb_set_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid);
if (IsMemoryDBActive(pid, write))
- return cert_memory_db_path;
+ return cert_memdb_path;
else
- return cert_file_db_path_;
+ return cert_filedb_path_;
}
-sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path,
+sqlite3* DBHandleProvider::CreateMemoryDBHandle(const std::string& filedb_path,
const std::string& memorydb_path) {
sqlite3* memorydb = nullptr;
sqlite3* filedb = nullptr;
void DBHandleProvider::SetMemoryMode(pid_t pid) {
std::unique_lock<std::recursive_mutex> u(lock_);
- if (is_memory_global_ && is_memory_)
+ if (is_global_memdb_set_ && is_user_memdb_set_)
return;
sqlite3* parser_db =
- GetMemoryDBHandle(parser_file_db_path_, parser_memory_db_path_);
+ CreateMemoryDBHandle(user_parser_filedb_path_, user_parser_memdb_path_);
if (parser_db != nullptr)
- parser_memory_db_handle_.reset(parser_db);
+ parser_memdb_handle_.reset(parser_db);
- if (is_memory_ == is_memory_global_) {
- sqlite3* global_parser_file_db = GetMemoryDBHandle(
- global_parser_file_db_path_, global_parser_memory_db_path);
+ if (is_user_memdb_set_ == is_global_memdb_set_) {
+ sqlite3* global_parser_file_db = CreateMemoryDBHandle(
+ global_parser_filedb_path_, global_parser_memdb_path);
if (global_parser_file_db)
- global_parser_memory_db_handle_.reset(global_parser_file_db);
+ global_parser_memdb_handle_.reset(global_parser_file_db);
+
sqlite3* cert_db =
- GetMemoryDBHandle(cert_file_db_path_, cert_memory_db_path);
+ CreateMemoryDBHandle(cert_filedb_path_, cert_memdb_path);
if (cert_db != nullptr)
- cert_memory_db_handle_.reset(cert_db);
+ cert_memdb_handle_.reset(cert_db);
InsertPID(pid);
}
- is_memory_ = true;
- is_memory_global_ = true;
+ is_user_memdb_set_ = true;
+ is_global_memdb_set_ = true;
LOG(DEBUG) << "Set Memory mode : Memory";
}
void DBHandleProvider::UnsetMemoryMode(pid_t pid) {
std::unique_lock<std::recursive_mutex> u(lock_);
- if (!is_memory_global_ && !is_memory_)
+ if (!is_global_memdb_set_ && !is_user_memdb_set_)
return;
- auto lock = CacheFlag::GetWriterLock();
- CacheFlag::SetStatus(CacheFlag::Status::PREPARING);
-
- parser_memory_db_handle_.reset(nullptr);
- cert_memory_db_handle_.reset(nullptr);
- global_parser_memory_db_handle_.reset(nullptr);
+ parser_memdb_handle_.reset(nullptr);
+ cert_memdb_handle_.reset(nullptr);
+ global_parser_memdb_handle_.reset(nullptr);
if (!ErasePID(pid))
LOG(ERROR) << "Given pid is not exists in pid list : " << pid;
- is_memory_ = false;
- is_memory_global_ = false;
- pkg_map_.clear();
- app_map_.clear();
- CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
+ is_user_memdb_set_ = false;
+ is_global_memdb_set_ = false;
+
LOG(DEBUG) << "Set Memory mode : File";
}
bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) {
- std::unique_lock<std::mutex> u(pid_list_lock_);
- return (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write);
+ std::unique_lock<std::shared_mutex> u(pid_list_lock_);
+ if (!is_user_memdb_set_)
+ return false;
+
+ if (write)
+ return false;
+
+ if (writer_pid_list_.find(pid) != writer_pid_list_.end())
+ return false;
+
+ return true;
}
void DBHandleProvider::TrimCache() {
app_map_.clear();
pkg_map_.clear();
+ pending_pkg_.clear();
+ pkg_app_map_.clear();
CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED);
released_ = true;
}
bool DBHandleProvider::IsWriter(pid_t pid) {
- std::unique_lock<std::mutex> u(pid_list_lock_);
- return pid_list_.find(pid) != pid_list_.end();
+ std::unique_lock<std::shared_mutex> s(pid_list_lock_);
+ return writer_pid_list_.find(pid) != writer_pid_list_.end();
}
int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
const std::string& locale) {
pkg_map_.clear();
app_map_.clear();
+ pending_pkg_.clear();
+ pkg_app_map_.clear();
+
+ const char* dbpath = sqlite3_db_filename(db, "main");
+ bool is_inmemory_db = false;
+ if (dbpath == nullptr || strlen(dbpath) == 0) {
+ LOG(INFO) << "database is inmemory db";
+ is_inmemory_db = true;
+ }
- GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
- if (list == nullptr) {
- LOG(ERROR) << "Out of memory";
+ timespec start_time = { 0, };
+ timespec end_time = { 0, };
+ if (!is_inmemory_db && !GetModifiedTime(dbpath, &start_time))
return PMINFO_R_ERROR;
- }
- auto tmp_filter = reinterpret_cast<pkgmgrinfo_filter_x*>(
- calloc(1, sizeof(pkgmgrinfo_filter_x)));
- if (tmp_filter == nullptr) {
+ GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
+ if (list == nullptr) {
LOG(ERROR) << "Out of memory";
- g_hash_table_destroy(list);
return PMINFO_R_ERROR;
}
- int ret = pkginfo_internal_filter_get_list(db, tmp_filter, uid_,
+ pkgmgrinfo_filter_x tmp_filter = { 0, };
+ tmp_filter.cache_flag = true;
+ int ret = pkginfo_internal_filter_get_list(db, &tmp_filter, uid_,
locale.c_str(), list);
if (ret == PMINFO_R_OK) {
GHashTableIter iter;
g_hash_table_iter_init(&iter, list);
while (g_hash_table_iter_next(&iter, nullptr, &value)) {
auto* pkg = reinterpret_cast<package_x*>(value);
- AddPackage(pkg->package, pkg);
+ std::string pkgid = pkg->package;
+ AddPackage(std::move(pkgid), pkg);
}
}
g_hash_table_destroy(list);
- if (ret == PMINFO_R_ERROR) {
- free(tmp_filter);
+ if (ret == PMINFO_R_ERROR)
return ret;
+
+ if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time))
+ return PMINFO_R_ERROR;
+
+ if (start_time.tv_sec != end_time.tv_sec ||
+ start_time.tv_nsec != end_time.tv_nsec) {
+ LOG(ERROR) << "Database(" << dbpath << ") modification was detected";
+ return PMINFO_R_ERROR;
+ }
+
+ std::vector<std::shared_ptr<application_x>> app_list;
+ ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
+ &tmp_filter, uid_, uid, locale.c_str(), app_list);
+
+ if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time))
+ return PMINFO_R_ERROR;
+
+ if (start_time.tv_sec != end_time.tv_sec ||
+ start_time.tv_nsec != end_time.tv_nsec) {
+ LOG(ERROR) << "Database(" << dbpath << ") modification was detected";
+ return PMINFO_R_ERROR;
}
- list = g_hash_table_new(g_str_hash, g_str_equal);
- ret = appinfo_internal_filter_get_list(db, tmp_filter, uid_, uid,
- locale.c_str(), list);
- free(tmp_filter);
if (ret == PMINFO_R_OK) {
- GHashTableIter iter;
- gpointer value;
- g_hash_table_iter_init(&iter, list);
- while (g_hash_table_iter_next(&iter, nullptr, &value)) {
- auto* app = reinterpret_cast<application_x*>(value);
- app->privileges = pkg_map_[app->package].front()->privileges;
- AddApplication(app->appid, app);
+ for (auto& app : app_list) {
+ auto it = pkg_map_.find(app->package);
+ if (it == pkg_map_.end()) {
+ LOG(ERROR) << "Can not find package from pkg_map";
+ return PMINFO_R_ERROR;
+ }
+
+ app->privileges = it->second->privileges;
+ std::string appid = app->appid;
+ AddApplication(std::move(appid), std::move(app));
}
}
- g_hash_table_destroy(list);
+
released_ = false;
return ret;
}
+inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter,
+ const std::shared_ptr<package_x>& info) {
+ for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
+ auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+ auto* checker = FilterCheckerProvider::GetInst().
+ GetPkgFilterChecker(node->prop);
+ if (!checker->CheckFilter(node, info.get()))
+ return false;
+ }
+
+ return true;
+}
+
std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
- pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
+ pid_t pid, pkgmgrinfo_filter_x* filter,
const std::string& package) {
std::vector<std::shared_ptr<package_x>> ret;
- for (auto& info : pkg_map_[package]) {
- bool pass = true;
- for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
- auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
- auto* checker = FilterCheckerProvider::GetInst().
- GetPkgFilterChecker(node->prop);
- if (!checker->CheckFilter(node, info.get())) {
- pass = false;
- break;
- }
+
+ if (__check_package_storage_status(filter)) {
+ if (pkgmgrinfo_pkginfo_filter_add_bool(filter,
+ PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, true) != PMINFO_R_OK) {
+ LOG(ERROR) << "Fail to add check storage value to filter";
+ return {};
}
- if (pass)
- ret.push_back(info);
+ }
+ if (package.empty()) {
+ for (auto& info : pkg_map_) {
+ if (CheckPkgFilters(filter, info.second))
+ ret.push_back(info.second);
+ }
+ } else {
+ auto map_it = pkg_map_.find(package);
+ if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second))
+ ret.push_back(map_it->second);
}
return ret;
void DBHandleProvider::AddPackage(std::string package, package_x* info) {
auto ptr = std::shared_ptr<package_x>(info, pkgmgrinfo_basic_free_package);
- pkg_map_[package].push_back(ptr);
- pkg_map_[""].push_back(std::move(ptr));
+ pkg_map_[package] = std::move(ptr);
}
-std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
- pid_t pid, bool write, pkgmgrinfo_filter_x* filter,
- const std::string& app) {
- /* make metadata filter map */
- std::unordered_map<std::string, std::string> metadata_map;
- for (auto* it = filter->list_metadata; it != nullptr; it = g_slist_next(it)) {
- auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
- if (node->key == nullptr)
- continue;
-
- metadata_map[node->key] = (node->value ? node->value : "");
- }
-
- std::vector<std::shared_ptr<application_x>> ret;
- for (auto& info : app_map_[app]) {
- bool pass = true;
+inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter,
+ const std::shared_ptr<application_x>& info,
+ const std::unordered_map<std::string, std::string>& metadata_map) {
for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
auto* checker = FilterCheckerProvider::GetInst().
GetAppFilterChecker(node->prop);
- if (!checker->CheckFilter(node, info.get())) {
- pass = false;
- break;
- }
+ if (!checker->CheckFilter(node, info.get()))
+ return false;
}
- if (!pass)
- continue;
+ bool pass = true;
if (!metadata_map.empty()) {
pass = false;
for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) {
auto* node = reinterpret_cast<metadata_x*>(it->data);
if (node->key != nullptr) {
auto metadata = metadata_map.find(node->key);
- if (metadata != metadata_map.end() &&
- strstr(node->value ? node->value : "",
- metadata->second.c_str()) != nullptr) {
- pass = true;
- break;
- }
+ if (metadata == metadata_map.end())
+ continue;
+
+ if (metadata->second.empty() ||
+ strcmp(node->value ? node->value : "",
+ metadata->second.c_str()) == 0)
+ return true;
}
}
}
- if (pass)
- ret.push_back(info);
+ return pass;
+}
+
+std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
+ pid_t pid, pkgmgrinfo_filter_x* filter,
+ const std::string& app) {
+ /* make metadata filter map */
+ std::unordered_map<std::string, std::string> metadata_map;
+ for (auto* it = filter->list_metadata; it != nullptr; it = g_slist_next(it)) {
+ auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
+ if (node->key == nullptr)
+ continue;
+
+ metadata_map[node->key] = (node->value ? node->value : "");
+ }
+
+ std::vector<std::shared_ptr<application_x>> ret;
+ if (pkgmgr_server::internal::check_app_storage_status(filter)) {
+ if (pkgmgrinfo_appinfo_filter_add_bool(filter,
+ PMINFO_APPINFO_PROP_APP_CHECK_STORAGE, true) != PMINFO_R_OK) {
+ LOG(ERROR) << "Fail to add check storage value to filter";
+ return {};
+ }
+ }
+
+ if (app.empty()) {
+ for (auto& info : app_map_) {
+ if (CheckAppFilters(filter, info.second, metadata_map))
+ ret.push_back(info.second);
+ }
+ } else {
+ auto map_it = app_map_.find(app);
+ if (map_it != app_map_.end() &&
+ CheckAppFilters(filter, map_it->second, metadata_map))
+ ret.push_back(map_it->second);
}
+
return ret;
}
-void DBHandleProvider::AddApplication(std::string app, application_x* info) {
- auto ptr =
- std::shared_ptr<application_x>(info, pkgmgrinfo_basic_free_application);
- app_map_[app].push_back(ptr);
- app_map_[""].push_back(std::move(ptr));
+void DBHandleProvider::AddApplication(std::string app,
+ std::shared_ptr<application_x> info) {
+ pkg_app_map_[info->package].emplace(app);
+ app_map_[app] = std::move(info);
}
void DBHandleProvider::InsertPID(pid_t pid) {
- std::unique_lock<std::mutex> u(pid_list_lock_);
+ std::unique_lock<std::shared_mutex> u(pid_list_lock_);
- pid_list_.insert(pid);
+ writer_pid_list_.insert(pid);
}
bool DBHandleProvider::ErasePID(pid_t pid) {
- std::unique_lock<std::mutex> u(pid_list_lock_);
+ std::unique_lock<std::shared_mutex> u(pid_list_lock_);
+
+ return writer_pid_list_.erase(pid) == 1;
+}
+
+void DBHandleProvider::RegisterPendingPackageInfo(
+ package_x* info, pid_t pid) {
+ if (!info || !info->package)
+ return;
+
+ pending_pkg_[pid].emplace(info->package);
+}
+
+bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db,
+ pid_t pid, uid_t uid, const std::string& locale) {
+ auto it = pending_pkg_.find(pid);
+ if (it == pending_pkg_.end()) {
+ LOG(WARNING) << "There is no package that is pending by the pid : " << pid;
+ return true;
+ }
+
+ GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
+ if (list == nullptr) {
+ LOG(ERROR) << "Out of memory";
+ return false;
+ }
+
+ pkgmgrinfo_filter_x tmp_filter = { 0, };
+ pkgmgrinfo_node_x node = {
+ .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID
+ };
+ tmp_filter.cache_flag = true;
+ tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+ for (const auto& pkg : it->second) {
+ pkg_map_.erase(pkg);
+ for (auto& appid : pkg_app_map_[pkg]) {
+ app_map_.erase(appid);
+ }
+
+ pkg_app_map_.erase(pkg);
+ node.value = const_cast<char*>(pkg.c_str());
+ pkginfo_internal_filter_get_list(db, &tmp_filter,
+ uid_, locale.c_str(), list);
+ }
+
+ GHashTableIter iter;
+ gpointer value;
+ g_hash_table_iter_init(&iter, list);
+ while (g_hash_table_iter_next(&iter, nullptr, &value)) {
+ auto* pkg = reinterpret_cast<package_x*>(value);
+ std::string pkgid = pkg->package;
+ AddPackage(std::move(pkgid), pkg);
+ }
+
+ g_hash_table_iter_init(&iter, list);
+ node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE;
+ while (g_hash_table_iter_next(&iter, nullptr, &value)) {
+ auto* pkg = reinterpret_cast<package_x*>(value);
+ node.value = pkg->package;
+ std::vector<std::shared_ptr<application_x>> app_list;
+ pkgmgr_server::internal::appinfo_internal_filter_get_list(
+ db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
+
+ for (auto& app : app_list) {
+ app->privileges = pkg->privileges;
+ std::string appid = app->appid;
+ AddApplication(std::move(appid), std::move(app));
+ }
+ }
+
+ g_hash_table_destroy(list);
+ g_slist_free(tmp_filter.list);
+ pending_pkg_.erase(pid);
+ return true;
+}
+
+bool DBHandleProvider::UpdateCachePkg(sqlite3* db, uid_t uid,
+ const std::string& pkgid, const std::string& locale) {
+ GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal);
+ if (list == nullptr) {
+ LOG(ERROR) << "Out of memory";
+ return false;
+ }
+
+ pkgmgrinfo_filter_x tmp_filter = { 0, };
+ pkgmgrinfo_node_x node = {
+ .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID,
+ .value = const_cast<char*>(pkgid.c_str())
+ };
+ tmp_filter.cache_flag = true;
+ tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+ pkginfo_internal_filter_get_list(db, &tmp_filter,
+ uid_, locale.c_str(), list);
+
+ GHashTableIter iter;
+ gpointer value;
+ g_hash_table_iter_init(&iter, list);
+ while (g_hash_table_iter_next(&iter, nullptr, &value)) {
+ auto* pkg = reinterpret_cast<package_x*>(value);
+ std::string pkgid = pkg->package;
+ AddPackage(pkgid, pkg);
+
+ for (auto& appid : pkg_app_map_[pkgid]) {
+ app_map_.erase(appid);
+ }
+
+ pkg_app_map_.erase(pkgid);
+
+ std::vector<std::shared_ptr<application_x>> app_list;
+ node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE;
+ node.value = const_cast<char*>(pkgid.c_str());
+
+ pkgmgr_server::internal::appinfo_internal_filter_get_list(
+ db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
+
+ for (auto& app : app_list) {
+ app->privileges = pkg->privileges;
+ std::string appid = app->appid;
+ AddApplication(std::move(appid), std::move(app));
+ }
+ }
+
+ g_hash_table_destroy(list);
+ g_slist_free(tmp_filter.list);
+ return true;
+}
+
+bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid,
+ const std::string& appid, const std::string& locale) {
+ pkgmgrinfo_filter_x tmp_filter = { 0, };
+ pkgmgrinfo_node_x node = {
+ .prop = E_PMINFO_APPINFO_PROP_APP_ID,
+ .value = const_cast<char*>(appid.c_str())
+ };
+ tmp_filter.cache_flag = true;
+ tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+
+ std::vector<std::shared_ptr<application_x>> app_list;
+ app_map_.erase(appid);
+ pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
+ &tmp_filter, uid_, uid, locale.c_str(), app_list);
+ g_slist_free(tmp_filter.list);
+
+ for (auto& app : app_list) {
+ auto it = pkg_map_.find(app->package);
+ if (it == pkg_map_.end()) {
+ LOG(ERROR) << "Can not find package from pkg_map";
+ return false;
+ }
+
+ pkg_app_map_[app->package].erase(app->appid);
+ app->privileges = it->second->privileges;
+ std::string appid = app->appid;
+ AddApplication(std::move(appid), std::move(app));
+ }
+
+ return true;
+}
+
+bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* db, uid_t uid,
+ const std::string& pkgid, const std::string& locale) {
+ auto it = pkg_map_.find(pkgid);
+ if (it == pkg_map_.end()) {
+ LOG(ERROR) << "Can not find package from pkg_map";
+ return false;
+ }
+
+ auto& pkg = it->second;
+ pkgmgrinfo_filter_x tmp_filter = { 0, };
+ pkgmgrinfo_node_x node = {
+ .prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE,
+ .value = pkg->package
+ };
+
+ tmp_filter.cache_flag = true;
+ tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node);
+
+ std::vector<std::shared_ptr<application_x>> app_list;
+ pkgmgr_server::internal::appinfo_internal_filter_get_list(
+ db, &tmp_filter, uid_, uid, locale.c_str(), app_list);
+
+ for (auto& appid : pkg_app_map_[pkgid]) {
+ app_map_.erase(appid);
+ }
+ pkg_app_map_.erase(pkgid);
+
+ for (auto& app : app_list) {
+ app->privileges = pkg->privileges;
+ std::string appid = app->appid;
+ AddApplication(std::move(appid), std::move(app));
+ }
- return pid_list_.erase(pid) == 1;
+ g_slist_free(tmp_filter.list);
+ return true;
}
} // namespace database