From b09cd188f7868995fc3239bc3ce4e9113e8c24d6 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 3 Apr 2019 16:44:54 +0900 Subject: [PATCH] Recycle pkgmgrinfo query result Change-Id: I720974e6697f3d9c0a79f02706f4dfbe661736ea Signed-off-by: Sangyoon Jang --- src/common/pkgmgr_query.cc | 70 +++++++++++++++++++++--------------- src/common/pkgmgr_query.h | 30 ++++++++++++++-- src/unit_tests/common/smoke_utils.cc | 10 +++--- 3 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/common/pkgmgr_query.cc b/src/common/pkgmgr_query.cc index f77d1d6..41deeb0 100644 --- a/src/common/pkgmgr_query.cc +++ b/src/common/pkgmgr_query.cc @@ -11,6 +11,7 @@ #include #include +#include namespace ci = common_installer; @@ -30,24 +31,36 @@ int PkgmgrForeachPluginCallback(const char* pkgid, const char* appid, namespace common_installer { -PkgQueryInterface::PkgQueryInterface(const std::string& pkgid, uid_t uid) - : pkgid_(pkgid), uid_(uid), handle_(nullptr) { - error_ = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkgid_.c_str(), uid_, - &handle_); +std::shared_ptr PkgQuery::GetResult( + const std::string& pkgid, uid_t uid, bool refresh) { + const auto& it = query_results_.find(std::make_pair(pkgid, uid)); + if (it != query_results_.end()) { + if (refresh) + query_results_.erase(it); + else + return it->second; + } + + pkgmgrinfo_pkginfo_h handle; + int error_ = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkgid.c_str(), uid, + &handle); if (error_ != PMINFO_R_OK) { - if (error_ != PMINFO_R_ENOENT) { + if (error_ != PMINFO_R_ENOENT) LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_pkginfo"; - handle_ = nullptr; - } + return nullptr; } + auto res = query_results_.emplace(std::make_pair(pkgid, uid), + std::make_shared(handle)); + return res.first->second; +} + +PkgQueryInterface::PkgQueryInterface(const std::string& pkgid, uid_t uid, + bool refresh) + : error_(0), pkgid_(pkgid), uid_(uid) { + handle_ = PkgQuery::Instance().GetResult(pkgid_, uid, refresh); } PkgQueryInterface::~PkgQueryInterface() { - if (handle_ != nullptr) { - int ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle_); - if (ret != PMINFO_R_OK) - LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_destroy_pkginfo"; - } } bool PkgQueryInterface::IsValid() { @@ -62,7 +75,7 @@ std::string PkgQueryInterface::TepPath() { if (!IsValid()) return {}; char* tep_name = nullptr; - error_ = pkgmgrinfo_pkginfo_get_tep_name(handle_, &tep_name); + error_ = pkgmgrinfo_pkginfo_get_tep_name(handle_->handle, &tep_name); if (error_ != PMINFO_R_OK) { LOG(DEBUG) << "pkgmgrinfo_pkginfo_get_tep_name failed with error: " << error_; @@ -78,7 +91,7 @@ std::string PkgQueryInterface::ZipMountFile() { if (!IsValid()) return {}; char* zip_mount_file = nullptr; - error_ = pkgmgrinfo_pkginfo_get_zip_mount_file(handle_, + error_ = pkgmgrinfo_pkginfo_get_zip_mount_file(handle_->handle, &zip_mount_file); if (error_ != PMINFO_R_OK) { LOG(DEBUG) << "pkgmgrinfo_pkginfo_get_zip_mount_file failed with error: " @@ -98,7 +111,7 @@ std::string PkgQueryInterface::StorageForPkgId() { std::string installed_location = "installed_internal"; pkgmgrinfo_installed_storage storage; - error_ = pkgmgrinfo_pkginfo_get_installed_storage(handle_, &storage); + error_ = pkgmgrinfo_pkginfo_get_installed_storage(handle_->handle, &storage); if (error_ != PMINFO_R_OK) return ""; @@ -115,7 +128,8 @@ bool PkgQueryInterface::IsPackageInstalled() { if (!IsValid()) return false; bool is_global = false; - if (pkgmgrinfo_pkginfo_is_for_all_users(handle_, &is_global) != PMINFO_R_OK) { + if (pkgmgrinfo_pkginfo_is_for_all_users(handle_->handle, &is_global) != + PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed"; return false; } @@ -131,7 +145,7 @@ bool PkgQueryInterface::IsPackageInstalled(RequestMode mode) { if (!IsValid()) return false; bool is_global = false; - error_ = pkgmgrinfo_pkginfo_is_for_all_users(handle_, &is_global); + error_ = pkgmgrinfo_pkginfo_is_for_all_users(handle_->handle, &is_global); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed"; return false; @@ -149,7 +163,7 @@ bool PkgQueryInterface::IsGlobalPackage() { if (!IsValid()) return false; bool is_global = false; - error_ = pkgmgrinfo_pkginfo_is_for_all_users(handle_, &is_global); + error_ = pkgmgrinfo_pkginfo_is_for_all_users(handle_->handle, &is_global); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed"; return false; @@ -161,7 +175,7 @@ bool PkgQueryInterface::IsReadonlyPackage() { if (!IsValid()) return false; bool is_readonly = false; - error_ = pkgmgrinfo_pkginfo_is_readonly(handle_, &is_readonly); + error_ = pkgmgrinfo_pkginfo_is_readonly(handle_->handle, &is_readonly); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_readonly failed"; return false; @@ -173,7 +187,7 @@ bool PkgQueryInterface::IsUpdatedPackage() { if (!IsValid()) return false; bool is_update = false; - error_ = pkgmgrinfo_pkginfo_is_update(handle_, &is_update); + error_ = pkgmgrinfo_pkginfo_is_update(handle_->handle, &is_update); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_update failed"; return false; @@ -185,7 +199,7 @@ bool PkgQueryInterface::IsPreloadPackage() { if (!IsValid()) return false; bool is_preload = false; - error_ = pkgmgrinfo_pkginfo_is_preload(handle_, &is_preload); + error_ = pkgmgrinfo_pkginfo_is_preload(handle_->handle, &is_preload); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_preload failed"; return false; @@ -197,7 +211,7 @@ bool PkgQueryInterface::IsSystemPackage() { if (!IsValid()) return false; bool is_system = false; - error_ = pkgmgrinfo_pkginfo_is_system(handle_, &is_system); + error_ = pkgmgrinfo_pkginfo_is_system(handle_->handle, &is_system); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_system failed"; return false; @@ -209,7 +223,7 @@ bool PkgQueryInterface::IsRemovablePackage() { if (!IsValid()) return false; bool is_removable = false; - error_ = pkgmgrinfo_pkginfo_is_removable(handle_, &is_removable); + error_ = pkgmgrinfo_pkginfo_is_removable(handle_->handle, &is_removable); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "pkgmgrinfo_pkginfo_is_removable failed"; return false; @@ -220,7 +234,7 @@ bool PkgQueryInterface::IsRemovablePackage() { bool PkgQueryInterface::AppidsForPkgId(std::vector* result) { if (!IsValid()) return false; - error_ = pkgmgrinfo_appinfo_get_usr_list(handle_, PMINFO_ALL_APP, + error_ = pkgmgrinfo_appinfo_get_usr_list(handle_->handle, PMINFO_ALL_APP, [](const pkgmgrinfo_appinfo_h handle, void* user_data) -> int { auto* data = static_cast*>(user_data); char* app_id = nullptr; @@ -236,7 +250,7 @@ bool PkgQueryInterface::AppidsForPkgId(std::vector* result) { bool PkgQueryInterface::PrivilegesForPkgId(std::vector* result) { if (!IsValid()) return false; - error_ = pkgmgrinfo_pkginfo_foreach_privilege(handle_, + error_ = pkgmgrinfo_pkginfo_foreach_privilege(handle_->handle, [](const char* privilege_name, void* user_data) -> int { auto* data = static_cast*>(user_data); data->emplace_back(privilege_name); @@ -250,7 +264,7 @@ bool PkgQueryInterface::PackagesDependsOn( std::vector* result) { if (!IsValid()) return false; - error_ = pkgmgrinfo_pkginfo_foreach_depends_on(handle_, + error_ = pkgmgrinfo_pkginfo_foreach_depends_on(handle_->handle, [](const char* from, const char* to, const char* type, const char* version, void* user_data) -> int { auto* data = @@ -268,7 +282,7 @@ bool PkgQueryInterface::IsPluginExecuted(const std::string& plugin_type, if (!IsValid()) return false; std::vector plugin_list; - error_ = pkgmgrinfo_pkginfo_foreach_plugin(handle_, + error_ = pkgmgrinfo_pkginfo_foreach_plugin(handle_->handle, &PkgmgrForeachPluginCallback, &plugin_list); if (error_ != PMINFO_R_OK) { LOG(ERROR) << "Failed to get plugin info"; @@ -289,7 +303,7 @@ bool PkgQueryInterface::PluginExecutionInfo( if (!IsValid()) return false; - error_ = pkgmgrinfo_pkginfo_foreach_plugin(handle_, + error_ = pkgmgrinfo_pkginfo_foreach_plugin(handle_->handle, &PkgmgrForeachPluginCallback, plugin_list); return error_ == PMINFO_R_OK; } diff --git a/src/common/pkgmgr_query.h b/src/common/pkgmgr_query.h index f435695..816f39b 100644 --- a/src/common/pkgmgr_query.h +++ b/src/common/pkgmgr_query.h @@ -7,15 +7,41 @@ #include #include +#include +#include +#include #include #include +#include #include #include "common/request.h" +#include "common/utils/singleton.h" namespace common_installer { +struct PkgHandle { + pkgmgrinfo_pkginfo_h handle; + explicit PkgHandle(pkgmgrinfo_pkginfo_h pkginfo_handle) { + handle = pkginfo_handle; + } + ~PkgHandle() { + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + } +}; + +class PkgQuery : public Singleton { + CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(PkgQuery) + public: + std::shared_ptr GetResult(const std::string& pkgid, uid_t uid, + bool refresh); + + private: + std::map, std::shared_ptr> + query_results_; +}; + /** * \brief Adapter interface for external PkgMgr module. */ @@ -25,7 +51,7 @@ class PkgQueryInterface { std::tuple; using DependencyInfo = std::tuple; - PkgQueryInterface(const std::string& pkgid, uid_t uid); + PkgQueryInterface(const std::string& pkgid, uid_t uid, bool refresh = false); PkgQueryInterface(const PkgQueryInterface&) = delete; PkgQueryInterface& operator=(const PkgQueryInterface&) = delete; ~PkgQueryInterface(); @@ -163,7 +189,7 @@ class PkgQueryInterface { int error_; std::string pkgid_; uid_t uid_; - pkgmgrinfo_pkginfo_h handle_; + std::shared_ptr handle_; }; /** diff --git a/src/unit_tests/common/smoke_utils.cc b/src/unit_tests/common/smoke_utils.cc index 39fa76f..5c7db50 100644 --- a/src/unit_tests/common/smoke_utils.cc +++ b/src/unit_tests/common/smoke_utils.cc @@ -342,7 +342,7 @@ static bool ValidatePackageFS(const std::string& pkgid, const Apps& apps, bool ValidatePackage(const std::string& pkgid, const Apps& apps, const TestParameters& params) { - ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid); + ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true); EXTENDED_ASSERT_TRUE(pkg_query.IsPackageInstalled( ci::GetRequestMode(params.test_user.uid))); EXTENDED_ASSERT_TRUE(ValidatePackageFS(pkgid, apps, params)); @@ -390,7 +390,7 @@ static bool ValidateExternalPackageFS(const std::string& pkgid, bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps, const TestParameters& params) { - ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid); + ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true); std::string storage = pkg_query.StorageForPkgId(); bf::path ext_mount_path = ci::GetExternalCardPath(); if (bf::is_empty(ext_mount_path)) { @@ -405,7 +405,7 @@ bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps, bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps, const TestParameters& params) { - ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid); + ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true); std::string storage = pkg_query.StorageForPkgId(); bf::path extended_path = bf::path(ci::GetExtendedRootAppPath(params.test_user.uid)) / pkgid; @@ -440,7 +440,7 @@ static bool PackageCheckCleanup(const std::string& pkgid, bool CheckPackageNonExistance(const std::string& pkgid, const TestParameters& params) { - ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid); + ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true); EXTENDED_ASSERT_FALSE(pkg_query.IsPackageInstalled( ci::GetRequestMode(params.test_user.uid))); EXTENDED_ASSERT_TRUE(PackageCheckCleanup(pkgid, params)); @@ -480,7 +480,7 @@ bool CheckAvailableExtendedPath() { bool CheckPackageReadonlyNonExistance(const std::string& pkgid, const TestParameters& params) { - ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid); + ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true); EXTENDED_ASSERT_FALSE(pkg_query.IsPackageInstalled( ci::GetRequestMode(params.test_user.uid))); EXTENDED_ASSERT_TRUE(PackageCheckCleanup(pkgid, params)); -- 2.7.4