Fix static analysis issue
[platform/core/appfw/app-installers.git] / src / common / pkgmgr_registration.cc
index 20658e3..71c2d64 100644 (file)
@@ -4,44 +4,71 @@
 
 #include "common/pkgmgr_registration.h"
 
+#include <manifest_parser/utils/logging.h>
 #include <pkgmgr_installer.h>
+#include <pkgmgr_parser_db.h>
 #include <tzplatform_config.h>
 #include <unistd.h>
 
-#include "common/utils/logging.h"
+#include <vector>
+#include <utility>
+
+#include "common/utils/glist_range.h"
+#include "common/utils/manifest_util.h"
 
 namespace bf = boost::filesystem;
 
+
 namespace {
 
-// TODO(sdi2): Check if data->removable is correctly setting
-// during parsing step.
-// Same check should be done for preload field.
+using CertInfo = common_installer::CertificateInfo;
+
+const char kWidgetApp[] = "widgetapp";
 
-// Having a specific step to implement a installer commandline tool
-// for image build could be usefull also.
-const char* const kAppinstTags[] = {"removable=true", nullptr, };
+bool RegisterCertificate(pkgmgr_instcertinfo_h handle,
+const ValidationCore::CertificatePtr& certPtr, pkgmgr_instcert_type type) {
+    if (certPtr) {
+      if (pkgmgr_installer_set_cert_value(handle, type,
+          const_cast<char*>(certPtr->getBase64().c_str())) < 0) {
+        pkgmgr_installer_destroy_certinfo_set_handle(handle);
+        LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
+        return false;
+      }
+    }
+    return true;
+}
 
-bool RegisterAuthorCertificate(
-    const common_installer::CertificateInfo& cert_info,
+typedef Property<ValidationCore::CertificatePtr> CertInfo::*PropertyOfCertInf;
+
+const std::vector<std::pair<PropertyOfCertInf, pkgmgr_instcert_type>>
+    kCertTypePairs = {
+  {&CertInfo::auth_cert, PM_SET_AUTHOR_SIGNER_CERT},
+  {&CertInfo::auth_im_cert, PM_SET_AUTHOR_INTERMEDIATE_CERT},
+  {&CertInfo::auth_root_cert, PM_SET_AUTHOR_ROOT_CERT},
+  {&CertInfo::dist_cert, PM_SET_DISTRIBUTOR_SIGNER_CERT},
+  {&CertInfo::dist_im_cert,
+      PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT},
+  {&CertInfo::dist_root_cert, PM_SET_DISTRIBUTOR_ROOT_CERT},
+  {&CertInfo::dist2_cert, PM_SET_DISTRIBUTOR2_SIGNER_CERT},
+  {&CertInfo::dist2_im_cert,
+      PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT},
+  {&CertInfo::dist2_root_cert, PM_SET_DISTRIBUTOR2_ROOT_CERT}
+};
+
+bool RegisterCertificates(
+    const CertInfo& cert_info,
     const std::string& pkgid, uid_t uid) {
   pkgmgr_instcertinfo_h handle;
   if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
     LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
     return false;
   }
-
-  const auto& cert = cert_info.author_certificate.get();
-
-  // TODO(t.iwanek): set other certificates if needed
-
-  if (pkgmgr_installer_set_cert_value(handle, PM_SET_AUTHOR_SIGNER_CERT,
-      const_cast<char*>(cert->getBase64().c_str())) < 0) {
-    pkgmgr_installer_destroy_certinfo_set_handle(handle);
-    LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
-    return false;
+  for (const auto& pair : kCertTypePairs) {
+     auto cert = (cert_info.*(pair.first)).get();
+     auto type = pair.second;
+     if (!RegisterCertificate(handle, cert, type))
+       return false;
   }
-
   if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
     pkgmgr_installer_destroy_certinfo_set_handle(handle);
     LOG(ERROR) << "Failed to save certificate information";
@@ -52,91 +79,117 @@ bool RegisterAuthorCertificate(
   return true;
 }
 
-int PkgmgrForeachAppCallback(const pkgmgrinfo_appinfo_h handle,
-                              void *user_data) {
-  auto* data = static_cast<std::vector<std::string>*>(user_data);
-  char* app_id = nullptr;
-  if (pkgmgrinfo_appinfo_get_appid(handle, &app_id) != PMINFO_R_OK)
-    return PMINFO_R_ERROR;
-  data->emplace_back(app_id);
-  return PMINFO_R_OK;
-}
-
-int PkgmgrForeachPrivilegeCallback(const char* privilege_name,
-                                   void* user_data) {
-  auto* data = static_cast<std::vector<std::string>*>(user_data);
-  data->emplace_back(privilege_name);
-  return PMINFO_R_OK;
+void AdjustWidgetNodisplayAttr(manifest_x* manifest) {
+  for (auto& app : GListRange<application_x*>(manifest->application)) {
+    if (!strcmp(app->component_type, kWidgetApp)) {
+      free(app->nodisplay);
+      // The nodisplay attribute of widget application should be true,
+      // but nodisplay of widget-service framework uses this attribute
+      // as defined at manifest file. So we need to adjust this value
+      // just before register in pkgmgr db.
+      app->nodisplay = strdup("true");
+    }
+  }
 }
 
-}  // anonymous namespace
+}  // namespace
 
 namespace common_installer {
 
-bool RegisterAppInPkgmgr(const bf::path& xml_path,
+bool RegisterAppInPkgmgr(manifest_x* manifest,
                          const std::string& pkgid,
                          const CertificateInfo& cert_info,
                          uid_t uid,
-                         RequestMode request_mode) {
+                         Storage storage,
+                         RequestMode request_mode,
+                         const boost::filesystem::path& tep_path) {
+  // Fill "non-xml" elements
+  if (!tep_path.empty())
+    manifest->tep_name = strdup(tep_path.c_str());
+
+  if (storage == Storage::EXTENDED) {
+    bf::path ext_path = bf::path(GetExtendedRootAppPath(uid)) / pkgid;
+    manifest->external_path = strdup(ext_path.c_str());
+  } else if (storage == Storage::EXTERNAL) {
+    App2ExtDynamicService service;
+    std::string image_path = service.GetExternalImagePath(pkgid.c_str(), uid);
+    if (!image_path.empty())
+      manifest->external_path = strdup(image_path.c_str());
+  }
+
+  AdjustWidgetNodisplayAttr(manifest);
+
   int ret = request_mode != RequestMode::GLOBAL ?
-      pkgmgr_parser_parse_usr_manifest_for_installation(
-          xml_path.c_str(), uid, const_cast<char* const*>(kAppinstTags)) :
-      pkgmgr_parser_parse_manifest_for_installation(
-          xml_path.c_str(), const_cast<char* const*>(kAppinstTags));
+      pkgmgr_parser_process_usr_manifest_x_for_installation(manifest, uid) :
+      pkgmgr_parser_process_manifest_x_for_installation(manifest);
   if (ret) {
-    LOG(ERROR) << "Failed to register package: " << xml_path << ", "
-        "error code=" << ret;
+    LOG(ERROR) << "Failed to insert manifest into pkgmgr, error code=" << ret;
     return false;
   }
 
-  if (!!cert_info.author_certificate.get()) {
-    if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
-      LOG(ERROR) << "Failed to register author certificate";
-      return false;
-    }
+  if (!RegisterCertificates(cert_info, pkgid, uid)) {
+    LOG(ERROR) << "Failed to register author certificate";
+    return false;
   }
 
   return true;
 }
 
-bool UpgradeAppInPkgmgr(const bf::path& xml_path, const std::string& pkgid,
-                        const CertificateInfo& cert_info, uid_t uid,
+bool UpgradeAppInPkgmgr(manifest_x* manifest,
+                        const std::string& pkgid,
+                        const CertificateInfo& cert_info,
+                        uid_t uid,
+                        Storage storage,
                         RequestMode request_mode) {
+  if (storage == Storage::EXTENDED) {
+    bf::path ext_path = bf::path(GetExtendedRootAppPath(uid)) / pkgid;
+    manifest->external_path = strdup(ext_path.c_str());
+  } else if (storage == Storage::EXTERNAL) {
+    App2ExtDynamicService service;
+    std::string image_path = service.GetExternalImagePath(pkgid.c_str(), uid);
+    if (!image_path.empty())
+      manifest->external_path = strdup(image_path.c_str());
+  }
+
+  AdjustWidgetNodisplayAttr(manifest);
+
   int ret = request_mode != RequestMode::GLOBAL ?
-       pkgmgr_parser_parse_usr_manifest_for_upgrade(
-           xml_path.string().c_str(), uid,
-           const_cast<char* const*>(kAppinstTags)) :
-       pkgmgr_parser_parse_manifest_for_upgrade(
-           xml_path.string().c_str(),
-           const_cast<char* const*>(kAppinstTags));
+       pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest, uid) :
+       pkgmgr_parser_process_manifest_x_for_upgrade(manifest);
 
   if (ret != 0) {
-    LOG(ERROR) << "Failed to upgrade package: " << xml_path;
+    LOG(ERROR) << "Failed to update manifest in pkgmgr, error code=" << ret;
     return false;
   }
 
   (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
-  if (!!cert_info.author_certificate.get()) {
-    if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
-      return false;
-    }
-  }
+  if (!RegisterCertificates(cert_info, pkgid, uid))
+    return false;
 
   return true;
 }
 
-bool UnregisterAppInPkgmgr(const bf::path& xml_path,
+bool UnregisterAppInPkgmgrForPkgId(const std::string& pkgid, uid_t uid,
+                                   RequestMode request_mode) {
+  manifest_x* manifest = PkgmgrGenerateManifestInfoFromDB(pkgid, uid);
+  if (!manifest) {
+    LOG(ERROR) << "Failed to get manifest_x from DB";
+    return false;
+  }
+  bool res = UnregisterAppInPkgmgr(manifest, pkgid, uid, request_mode);
+  pkgmgr_parser_free_manifest_xml(manifest);
+  return res;
+}
+
+bool UnregisterAppInPkgmgr(manifest_x* manifest,
                            const std::string& pkgid,
                            uid_t uid,
                            RequestMode request_mode) {
   int ret = request_mode != RequestMode::GLOBAL ?
-      pkgmgr_parser_parse_usr_manifest_for_uninstallation(
-          xml_path.string().c_str(), uid,
-          const_cast<char* const*>(kAppinstTags)) :
-      pkgmgr_parser_parse_manifest_for_uninstallation(
-          xml_path.string().c_str(), const_cast<char* const*>(kAppinstTags));
+      pkgmgr_parser_process_usr_manifest_x_for_uninstallation(manifest, uid) :
+      pkgmgr_parser_process_manifest_x_for_uninstallation(manifest);
   if (ret) {
-    LOG(ERROR) << "Failed to unregister package: " << xml_path;
+    LOG(ERROR) << "Failed to delete manifest from pkgmgr, error code=" << ret;
     return false;
   }
 
@@ -146,86 +199,109 @@ bool UnregisterAppInPkgmgr(const bf::path& xml_path,
   return true;
 }
 
-std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
-                                              uid_t uid) {
-  pkgmgrinfo_certinfo_h handle;
-  int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
-  if (ret != PMINFO_R_OK) {
-    LOG(ERROR) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
-               << ret;
-    return {};
-  }
-  ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, uid);
-  if (ret != PMINFO_R_OK) {
-    LOG(ERROR) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
-    pkgmgrinfo_pkginfo_destroy_certinfo(handle);
-    return {};
-  }
-  const char* author_cert = nullptr;
-  ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
-                                          &author_cert);
-  if (ret != PMINFO_R_OK) {
-    LOG(ERROR) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
-               << ret;
-    pkgmgrinfo_pkginfo_destroy_certinfo(handle);
-    return {};
-  }
-  std::string old_author_certificate;
-  if (author_cert)
-    old_author_certificate = author_cert;
-  pkgmgrinfo_pkginfo_destroy_certinfo(handle);
-  return old_author_certificate;
-}
-
+bool UpdateTepInfoInPkgmgr(const bf::path& tep_path, const std::string& pkgid,
+                        uid_t uid, RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+        pkgmgr_parser_usr_update_tep(
+            pkgid.c_str(), tep_path.string().c_str(), uid) :
+        pkgmgr_parser_update_tep(
+            pkgid.c_str(), tep_path.string().c_str());
 
-bool QueryAppidsForPkgId(const std::string& pkg_id,
-                         std::vector<std::string>* result, uid_t uid) {
-  pkgmgrinfo_pkginfo_h package_info;
-  if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
-      != PMINFO_R_OK) {
+  if (ret != 0) {
+    LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
     return false;
   }
 
-  bool ret = pkgmgrinfo_appinfo_get_usr_list(package_info, PMINFO_ALL_APP,
-      &PkgmgrForeachAppCallback, result, uid) == PMINFO_R_OK;
-  pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
-  return ret;
+  return true;
 }
 
-bool QueryPrivilegesForPkgId(const std::string& pkg_id,
-                             std::vector<std::string>* result, uid_t uid) {
-  pkgmgrinfo_pkginfo_h package_info;
-  if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &package_info)
-      != PMINFO_R_OK) {
+bool UpdateInstalledStorageInPkgmgr(Storage storage, const bf::path& ext_path,
+                                    const std::string& pkgid, uid_t uid) {
+  // FIXME: refactor this
+  INSTALL_LOCATION install_location;
+  const char* path;
+  if (storage == Storage::INTERNAL) {
+    install_location = INSTALL_INTERNAL;
+    path = "";
+  } else if (storage == Storage::EXTERNAL) {
+    install_location = INSTALL_EXTERNAL;
+    path = ext_path.string().c_str();
+  } else {
+    install_location = INSTALL_EXTENDED;
+    path = ext_path.string().c_str();
+  }
+  int ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(
+      pkgid.c_str(), install_location, path, uid);
+  if (ret != 0) {
+    LOG(ERROR) << "Failed to update installed storage info: " << pkgid;
     return false;
   }
 
-  bool ret = pkgmgrinfo_pkginfo_foreach_privilege(package_info,
-      &PkgmgrForeachPrivilegeCallback, result) == PMINFO_R_OK;
-  pkgmgrinfo_pkginfo_destroy_pkginfo(package_info);
-  return ret;
+  return true;
 }
 
-bool IsPackageInstalled(const std::string& pkg_id, RequestMode request_mode) {
-  pkgmgrinfo_pkginfo_h handle;
-  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
-                                               &handle);
-  if (ret != PMINFO_R_OK)
+bool DisablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
+                        RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+        pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 1) :
+        pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 1);
+  if (ret != 0) {
+    LOG(ERROR) << "Failed to disable pkg: " << pkgid;
     return false;
-  bool is_global = false;
-  if (pkgmgrinfo_pkginfo_is_for_all_users(handle, &is_global) != PMINFO_R_OK) {
-    LOG(ERROR) << "pkgmgrinfo_pkginfo_is_for_all_users failed";
-    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+  }
+
+  return true;
+}
+
+bool EnablePkgInPkgmgr(const std::string& pkgid, uid_t uid,
+    RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+        pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid.c_str(), uid, 0) :
+        pkgmgr_parser_update_pkg_disable_info_in_db(pkgid.c_str(), 0);
+  if (ret != 0) {
+    LOG(ERROR) << "Failed to enable pkg: " << pkgid;
     return false;
   }
-  if (request_mode != RequestMode::GLOBAL && is_global) {
-    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+  return true;
+}
+
+bool RegisterPluginInfo(manifest_x* manifest,
+                        uid_t uid,
+                        RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+      pkgmgr_parser_register_pkg_plugin_info_in_usr_db(manifest, uid) :
+      pkgmgr_parser_register_pkg_plugin_info_in_db(manifest);
+  if (ret) {
+    LOG(ERROR) << "Failed to insert plugin info, error code=" << ret;
     return false;
   }
+  return true;
+}
 
-  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+bool UpdatePluginInfo(manifest_x* manifest,
+                      uid_t uid, RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+      pkgmgr_parser_update_pkg_plugin_info_in_usr_db(manifest, uid) :
+      pkgmgr_parser_update_pkg_plugin_info_in_db(manifest);
+  if (ret) {
+    LOG(ERROR) << "Failed to insert update plugin info, error code=" << ret;
+    return false;
+  }
   return true;
 }
 
+bool UnregisterPluginInfo(const std::string& pkgid,
+                          uid_t uid,
+                          RequestMode request_mode) {
+  int ret = request_mode != RequestMode::GLOBAL ?
+      pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid.c_str(), uid) :
+      pkgmgr_parser_unregister_pkg_plugin_info_in_db(pkgid.c_str());
+  if (ret) {
+    LOG(ERROR) << "Failed to remove plugin info, error code=" << ret;
+    return false;
+  }
+  return true;
+}
 
 }  // namespace common_installer