X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fserver%2Fdatabase%2Fdb_handle_provider.cc;h=5576c67b03403c7a93c6efe933c3910958f9cf2c;hb=434d13dc56657c25c3a3b709e1ae59e22842c5a0;hp=6b3579fe6a5bbb05f379bce4d89d21cbabf5c623;hpb=c3dcd399d494bae080a83ba5e80ed367b0a412b2;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git diff --git a/src/server/database/db_handle_provider.cc b/src/server/database/db_handle_provider.cc index 6b3579f..5576c67 100644 --- a/src/server/database/db_handle_provider.cc +++ b/src/server/database/db_handle_provider.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -57,11 +58,23 @@ uid_t ConvertUID(uid_t uid) { return uid; } -static const std::string global_parser_memory_db_path = - "file:parserdb?mode=memory&cache=shared"; +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; + } -static const std::string cert_memory_db_path = - "file:certdb?mode=memory&cache=shared"; + *t = attr.st_mtim; + + return true; +} } // namespace @@ -69,103 +82,81 @@ namespace pkgmgr_server { namespace database { std::unordered_map> - DBHandleProvider::provider_; -bool DBHandleProvider::is_memory_global_ = false; -std::unique_ptr - DBHandleProvider::global_parser_memory_db_handle_(nullptr, - sqlite3_close_v2); -std::unique_ptr - 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 DBHandleProvider::pid_list_; -std::recursive_mutex DBHandleProvider::lock_; -std::mutex DBHandleProvider::pid_list_lock_; - -DBHandleProvider::DBHandleProvider(uid_t uid) - : uid_(uid), - is_memory_(false), - parser_memory_db_handle_(nullptr, sqlite3_close_v2) { + DBHandleProvider::provider_map_; +std::string DBHandleProvider::global_parser_filedb_path_; +std::string DBHandleProvider::cert_filedb_path_; +std::unordered_set DBHandleProvider::writer_pid_list_; +std::shared_mutex DBHandleProvider::pid_list_lock_; + +DBHandleProvider::DBHandleProvider(uid_t uid) : uid_(uid) { 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(uid_)) + - "?mode=memory&cache=shared"; } DBHandleProvider& DBHandleProvider::GetInst(uid_t uid) { - static std::mutex singleton_lock_; - std::unique_lock u(singleton_lock_); + static std::shared_mutex singleton_lock_; + std::shared_lock 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 u(singleton_lock_); + auto& prov = provider_map_[uid]; if (prov == nullptr) prov.reset(new DBHandleProvider(uid)); return *prov; } -bool DBHandleProvider::IsCrashedWriteRequest() { - std::unique_lock u(pid_list_lock_); +std::unordered_set DBHandleProvider::CrashedWriteRequestPIDs() { + std::unique_lock u(pid_list_lock_); - if (pid_list_.empty()) - return false; + if (writer_pid_list_.empty()) + return {}; - bool ret = true; - LOG(DEBUG) << "Check process count : " << pid_list_.size(); - std::vector remove_pids; - for (pid_t pid : pid_list_) { + LOG(DEBUG) << "Check process count : " << writer_pid_list_.size(); + std::unordered_set remove_pids; + 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); if (fd < 0) { LOG(ERROR) << "Process is crashed : " << pid; - remove_pids.push_back(pid); + remove_pids.emplace(pid); } else { - ret = false; close(fd); } } - for (pid_t pid : remove_pids) - pid_list_.erase(pid); - - return ret; + return remove_pids; } -std::vector> DBHandleProvider::GetParserDBPath( - pid_t pid, bool write) { - std::unique_lock u(lock_); +std::vector> DBHandleProvider::GetParserDBPath() { std::vector> db_path_list; - if (is_memory_ != is_memory_global_) - is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid); + if (uid_ > REGULAR_USER) + db_path_list.emplace_back(std::make_pair(user_parser_filedb_path_, uid_)); - 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(global_parser_memory_db_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(global_parser_file_db_path_, GetGlobalUID())); - } + db_path_list.emplace_back( + std::make_pair(global_parser_filedb_path_, GetGlobalUID())); if (db_path_list.size() == 1) { LOG(DEBUG) << "global db path : " << db_path_list[0].first; @@ -177,109 +168,11 @@ std::vector> DBHandleProvider::GetParserDBPath( return db_path_list; } -std::string DBHandleProvider::GetCertDBPath(pid_t pid, bool write) { - std::unique_lock u(lock_); - if (is_memory_ != is_memory_global_) - is_memory_global_ ? SetMemoryMode(pid) : UnsetMemoryMode(pid); - - if (IsMemoryDBActive(pid, write)) - return cert_memory_db_path; - else - return cert_file_db_path_; -} - -sqlite3* DBHandleProvider::GetMemoryDBHandle(const std::string& filedb_path, - const std::string& memorydb_path) { - sqlite3* memorydb = nullptr; - sqlite3* filedb = nullptr; - int ret = sqlite3_open_v2(memorydb_path.c_str(), &memorydb, - SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, nullptr); - if (ret != SQLITE_OK) { - LOG(ERROR) << "Failed to open memory DB " << ret << ": " << memorydb_path; - return nullptr; - } - - ret = sqlite3_open_v2(filedb_path.c_str(), &filedb, SQLITE_OPEN_READONLY, - nullptr); - if (ret != SQLITE_OK) { - LOG(ERROR) << "Failed to open file DB " << ret << ": " << filedb_path; - sqlite3_close_v2(memorydb); - return nullptr; - } - - sqlite3_backup* backup = - sqlite3_backup_init(memorydb, "main", filedb, "main"); - if (backup == nullptr) { - LOG(ERROR) << "Failed to backup for memory DB"; - sqlite3_close_v2(memorydb); - sqlite3_close_v2(filedb); - return nullptr; - } - - sqlite3_backup_step(backup, -1); - sqlite3_backup_finish(backup); - sqlite3_close_v2(filedb); - return memorydb; -} - -void DBHandleProvider::SetMemoryMode(pid_t pid) { - std::unique_lock u(lock_); - if (is_memory_global_ && is_memory_) - return; - - sqlite3* parser_db = - GetMemoryDBHandle(parser_file_db_path_, parser_memory_db_path_); - if (parser_db != nullptr) - parser_memory_db_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 (global_parser_file_db) - global_parser_memory_db_handle_.reset(global_parser_file_db); - sqlite3* cert_db = - GetMemoryDBHandle(cert_file_db_path_, cert_memory_db_path); - if (cert_db != nullptr) - cert_memory_db_handle_.reset(cert_db); - - InsertPID(pid); - } - - is_memory_ = true; - is_memory_global_ = true; - LOG(DEBUG) << "Set Memory mode : Memory"; -} - -void DBHandleProvider::UnsetMemoryMode(pid_t pid) { - std::unique_lock u(lock_); - if (!is_memory_global_ && !is_memory_) - 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); - - 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); - LOG(DEBUG) << "Set Memory mode : File"; -} - -bool DBHandleProvider::IsMemoryDBActive(pid_t pid, bool write) { - std::unique_lock u(pid_list_lock_); - return (is_memory_ && pid_list_.find(pid) == pid_list_.end() && !write); +std::string DBHandleProvider::GetCertDBPath() { + return cert_filedb_path_; } void DBHandleProvider::TrimCache() { - std::unique_lock u(lock_); if (!released_) ReleaseCache(); } @@ -290,103 +183,204 @@ void DBHandleProvider::ReleaseCache() { 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 u(pid_list_lock_); - return pid_list_.find(pid) != pid_list_.end(); + std::unique_lock 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) { +int DBHandleProvider::UpdateCache(const tizen_base::Database& 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(); - GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal); - if (list == nullptr) { - LOG(ERROR) << "Out of memory"; + const char* dbpath = sqlite3_db_filename(db.GetRaw(), "main"); + + timespec start_time = { 0, }; + timespec end_time = { 0, }; + if (!GetModifiedTime(dbpath, &start_time)) return PMINFO_R_ERROR; + + pkgmgrinfo_filter_x tmp_filter = { 0, }; + tmp_filter.cache_flag = true; + std::map> pkgs; + int ret = internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); + if (ret == PMINFO_R_OK) { + for (auto& [key, val] : pkgs) + AddPackage(std::move(val)); } - auto tmp_filter = reinterpret_cast( - calloc(1, sizeof(pkgmgrinfo_filter_x))); - if (tmp_filter == nullptr) { - LOG(ERROR) << "Out of memory"; - g_hash_table_destroy(list); + if (!GetModifiedTime(dbpath, &end_time)) return PMINFO_R_ERROR; - } - int ret = pkginfo_internal_filter_get_list(db, tmp_filter, uid_, - locale.c_str(), list); - 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* pkg = reinterpret_cast(value); - AddPackage(pkg->package, pkg); - } + 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; } - g_hash_table_destroy(list); - if (ret == PMINFO_R_ERROR) { - free(tmp_filter); - return ret; + std::vector> app_list; + ret = internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); + + if (!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(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; + AddApplication(std::move(app)); } } - g_hash_table_destroy(list); + released_ = false; return ret; } +inline bool CheckMetadataFilter(GList* metadata_list, + const std::unordered_map& metadata_map) { + for (auto* it = metadata_list; it != nullptr; it = g_list_next(it)) { + auto* node = reinterpret_cast(it->data); + if (node->key != nullptr) { + auto metadata = metadata_map.find(node->key); + if (metadata == metadata_map.end()) + continue; + + if (metadata->second.empty() || + strcmp(node->value ? node->value : "", metadata->second.c_str()) == 0) + return true; + } + } + return false; +} + +inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter, + const std::shared_ptr& info, + const std::unordered_map& metadata_map) { + for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { + auto node = reinterpret_cast(it->data); + auto* checker = FilterCheckerProvider::GetInst(). + GetPkgFilterChecker(node->prop); + if (!checker->CheckFilter(node, info.get())) + return false; + } + + bool pass = true; + if (!metadata_map.empty()) + pass = CheckMetadataFilter(info->metadata, metadata_map); + + return pass; +} + std::vector> DBHandleProvider::GetPackages( - pid_t pid, bool write, pkgmgrinfo_filter_x* filter, + pid_t pid, pkgmgrinfo_filter_x* filter, const std::string& package) { std::vector> 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(it->data); - auto* checker = FilterCheckerProvider::GetInst(). - GetPkgFilterChecker(node->prop); - if (!checker->CheckFilter(node, info.get())) { - pass = false; - break; - } + + /* make metadata filter map */ + std::unordered_map metadata_map; + for (auto* it = filter->list_pkg_metadata; it != nullptr; + it = g_slist_next(it)) { + auto node = reinterpret_cast(it->data); + if (node->key == nullptr) + continue; + LOG(ERROR) << "add metadata filter"; + metadata_map[node->key] = (node->value ? node->value : ""); + } + + if (internal::CheckPackageStorageStatus(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, metadata_map)) + ret.push_back(info.second); + } + } else { + auto map_it = pkg_map_.find(package); + if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second, + metadata_map)) + ret.push_back(map_it->second); } return ret; } -void DBHandleProvider::AddPackage(std::string package, package_x* info) { - auto ptr = std::shared_ptr(info, pkgmgrinfo_basic_free_package); - pkg_map_[package].push_back(ptr); - pkg_map_[""].push_back(std::move(ptr)); +void DBHandleProvider::AddPackage(std::shared_ptr info) { + pkg_map_[info->package] = std::move(info); +} + +void DBHandleProvider::AddApplication(std::shared_ptr info) { + std::string appid = info->appid; + std::string pkgid = info->package; + app_map_[appid] = std::move(info); + pkg_app_map_[pkgid].emplace(std::move(appid)); +} + +void DBHandleProvider::ErasePackage(const std::string& pkgid) { + auto it = pkg_app_map_.find(pkgid); + if (it != pkg_app_map_.end()) { + for (const auto& app : it->second) + app_map_.erase(app); + pkg_app_map_.erase(it); + } + + pkg_map_.erase(pkgid); +} + +inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter, + const std::shared_ptr& app_info, + const std::shared_ptr& pkg_info, + const std::unordered_map& metadata_map) { + for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { + auto node = reinterpret_cast(it->data); + auto* checker = FilterCheckerProvider::GetInst(). + GetAppFilterChecker(node->prop); + if (!checker->CheckFilter(node, app_info.get(), pkg_info.get())) + return false; + } + + bool pass = true; + if (!metadata_map.empty()) + pass = CheckMetadataFilter(app_info->metadata, metadata_map); + return pass; +} + +std::shared_ptr DBHandleProvider::GetPackageByApp( + const char* appid) { + auto it = pkg_map_.find(appid); + if (it == pkg_map_.end()) + return nullptr; + + return it->second; } std::vector> DBHandleProvider::GetApplications( - pid_t pid, bool write, pkgmgrinfo_filter_x* filter, + pid_t pid, pkgmgrinfo_filter_x* filter, const std::string& app) { /* make metadata filter map */ std::unordered_map metadata_map; @@ -399,59 +393,232 @@ std::vector> DBHandleProvider::GetApplications( } std::vector> ret; - for (auto& info : app_map_[app]) { - bool pass = true; - for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) { - auto node = reinterpret_cast(it->data); - auto* checker = FilterCheckerProvider::GetInst(). - GetAppFilterChecker(node->prop); - if (!checker->CheckFilter(node, info.get())) { - pass = false; - break; + if (internal::CheckAppStorageStatus(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, + GetPackageByApp(info.second->package), 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, + GetPackageByApp(map_it->second->package), metadata_map)) + ret.push_back(map_it->second); + } + + return ret; +} + +void DBHandleProvider::InsertWriterPID(pid_t pid) { + std::unique_lock u(pid_list_lock_); + + writer_pid_list_.insert(pid); +} + +bool DBHandleProvider::EraseWriterPID(pid_t pid) { + std::unique_lock u(pid_list_lock_); + + return writer_pid_list_.erase(pid) == 1; +} + +void DBHandleProvider::RegisterPendingPackageInfo( + const tizen_base::Database& db, package_x* info, pid_t pid, uid_t uid, + const std::string& locale, pkgmgr_common::PkgWriteType write_type) { + if (!info || !info->package) + return; + + InsertWriterPID(pid); + + if (write_type != pkgmgr_common::PkgWriteType::Delete) { + 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); + std::map> pkgs; + + node.value = const_cast(info->package); + internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); + node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE; + for (auto& [pkgid, pkg_handle] : pkgs) { + node.value = const_cast(pkgid.c_str()); + std::vector> app_list; + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); + + for (auto& app : app_list) { + app->privileges = pkg_handle->privileges; + pending_app_[pkgid].emplace_back(std::move(app)); } + + pending_pkg_[pkgid] = std::make_pair(pid, std::move(pkg_handle)); } - if (!pass) + + g_slist_free(tmp_filter.list); + } else { + pending_pkg_[info->package] = std::make_pair(pid, nullptr); + pending_app_.erase(info->package); + } +} + +void DBHandleProvider::UpdatePendingPackageInfo( + const std::vector& pkgids) { + for (const auto& pkgid : pkgids) { + auto pkg_it = pending_pkg_.find(pkgid); + if (pkg_it == pending_pkg_.end()) continue; - if (!metadata_map.empty()) { - pass = false; - for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) { - auto* node = reinterpret_cast(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; - } - } - } + ErasePackage(pkgid); + auto app_it = pending_app_.find(pkgid); + if (app_it != pending_app_.end()) { + for (auto& app : app_it->second) + AddApplication(std::move(app)); + pending_app_.erase(app_it); } - if (pass) - ret.push_back(info); + if (pkg_it->second.second) + AddPackage(std::move(pkg_it->second.second)); + + EraseWriterPID(pkg_it->second.first); + pending_pkg_.erase(pkg_it); + } +} + +void DBHandleProvider::UpdateCrashedWriterPackageInfo( + const std::unordered_set& pids) { + for (auto it = pending_pkg_.begin(); it != pending_pkg_.end();) { + pid_t pid = it->second.first; + if (pids.find(pid) == pids.end()) { + it++; + continue; + } + + const auto& pkgid = it->first; + auto old_app_it = pkg_app_map_.find(pkgid); + if (old_app_it != pkg_app_map_.end()) { + for (const auto& app : old_app_it->second) + app_map_.erase(app); + + pkg_app_map_.erase(old_app_it); + } + + auto app_it = pending_app_.find(pkgid); + if (app_it != pending_app_.end()) { + for (auto& app : app_it->second) + AddApplication(std::move(app)); + pending_app_.erase(app_it); + } + + if (it->second.second) + AddPackage(std::move(it->second.second)); + + EraseWriterPID(it->second.first); + it = pending_pkg_.erase(it); } - return ret; } -void DBHandleProvider::AddApplication(std::string app, application_x* info) { - auto ptr = - std::shared_ptr(info, pkgmgrinfo_basic_free_application); - app_map_[app].push_back(ptr); - app_map_[""].push_back(std::move(ptr)); +bool DBHandleProvider::UpdateCachePkg(const tizen_base::Database& db, uid_t uid, + const std::string& pkgid, const std::string& locale) { + pkgmgrinfo_filter_x tmp_filter = { 0, }; + pkgmgrinfo_node_x node = { + .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID, + .value = const_cast(pkgid.c_str()) + }; + tmp_filter.cache_flag = true; + tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); + std::map> pkgs; + internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); + for (auto& [key, val] : pkgs) { + AddPackage(val); + for (auto& appid : pkg_app_map_[key]) + app_map_.erase(appid); + + pkg_app_map_.erase(key); + std::vector> app_list; + node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE; + node.value = const_cast(key.c_str()); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); + for (auto& app : app_list) { + app->privileges = val->privileges; + AddApplication(std::move(app)); + } + } + + return true; } -void DBHandleProvider::InsertPID(pid_t pid) { - std::unique_lock u(pid_list_lock_); +bool DBHandleProvider::UpdateCacheApp(const tizen_base::Database& 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(appid.c_str()) + }; + tmp_filter.cache_flag = true; + tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); + + std::vector> app_list; + app_map_.erase(appid); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, 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; + AddApplication(std::move(app)); + } - pid_list_.insert(pid); + return true; } -bool DBHandleProvider::ErasePID(pid_t pid) { - std::unique_lock u(pid_list_lock_); +bool DBHandleProvider::UpdateCacheAppByPkgid(const tizen_base::Database& 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> app_list; + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, 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; + AddApplication(std::move(app)); + } - return pid_list_.erase(pid) == 1; + g_slist_free(tmp_filter.list); + return true; } } // namespace database