Recycle pkgmgrinfo query result 23/202723/5
authorSangyoon Jang <jeremy.jang@samsung.com>
Wed, 3 Apr 2019 07:44:54 +0000 (16:44 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Tue, 16 Apr 2019 02:06:52 +0000 (02:06 +0000)
Change-Id: I720974e6697f3d9c0a79f02706f4dfbe661736ea
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/common/pkgmgr_query.cc
src/common/pkgmgr_query.h
src/unit_tests/common/smoke_utils.cc

index f77d1d6..41deeb0 100644 (file)
@@ -11,6 +11,7 @@
 #include <tzplatform_config.h>
 
 #include <cstring>
+#include <utility>
 
 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<PkgHandle> 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<PkgHandle>(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<std::string>* 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<std::vector<std::string>*>(user_data);
         char* app_id = nullptr;
@@ -236,7 +250,7 @@ bool PkgQueryInterface::AppidsForPkgId(std::vector<std::string>* result) {
 bool PkgQueryInterface::PrivilegesForPkgId(std::vector<std::string>* 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<std::vector<std::string>*>(user_data);
         data->emplace_back(privilege_name);
@@ -250,7 +264,7 @@ bool PkgQueryInterface::PackagesDependsOn(
     std::vector<DependencyInfo>* 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<PluginInfo> 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;
 }
index f435695..816f39b 100644 (file)
@@ -7,15 +7,41 @@
 
 #include <unistd.h>
 #include <pkgmgr-info.h>
+#include <sys/types.h>
 
+#include <map>
+#include <memory>
 #include <string>
 #include <tuple>
+#include <utility>
 #include <vector>
 
 #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<PkgQuery> {
+  CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(PkgQuery)
+ public:
+  std::shared_ptr<PkgHandle> GetResult(const std::string& pkgid, uid_t uid,
+      bool refresh);
+
+ private:
+  std::map<std::pair<std::string, uid_t>, std::shared_ptr<PkgHandle>>
+      query_results_;
+};
+
 /**
  * \brief Adapter interface for external PkgMgr module.
  */
@@ -25,7 +51,7 @@ class PkgQueryInterface {
       std::tuple<std::string, std::string, std::string, std::string>;
   using DependencyInfo =
       std::tuple<std::string, std::string, std::string, std::string>;
-  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<PkgHandle> handle_;
 };
 
 /**
index 39fa76f..5c7db50 100644 (file)
@@ -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));