Find the package type from package's xml file 20/294120/4
authorilho kim <ilho159.kim@samsung.com>
Tue, 13 Jun 2023 08:40:34 +0000 (17:40 +0900)
committerilho kim <ilho159.kim@samsung.com>
Mon, 19 Jun 2023 07:25:44 +0000 (16:25 +0900)
Package types needs to be identified from xml file for package
that don't exist in the database when manifest direct type's
installation

Change-Id: Ib610564308338baa3351da9f0b79cefe2fb874b4
Signed-off-by: ilho kim <ilho159.kim@samsung.com>
CMakeLists.txt
packaging/unified-backend.spec
src/unified/CMakeLists.txt
src/unified/unified_installer_factory.cc
src/unified/unified_installer_factory.h

index b716af1f2a37568f8fd5d84cb8d556d713b44046..91e800dbf5079f280605353df17d6cba295b51d4 100644 (file)
@@ -56,6 +56,7 @@ PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
 PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
 PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
 PKG_CHECK_MODULES(RPK_INSTALLER_DEPS REQUIRED rpk-installer)
+PKG_CHECK_MODULES(LIBXML_DEPS REQUIRED libxml-2.0)
 
 FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem regex program_options)
 
index e0f41565c58919d92c32b7a14d2445bd9fe55b5c..5821175a8da9b3153c9e4298f955785fcc2195b0 100644 (file)
@@ -29,6 +29,7 @@ BuildRequires: pkgconfig(gmock)
 BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(rpk-installer)
+BuildRequires: pkgconfig(libxml-2.0)
 
 %if 0%{?gcov:1}
 BuildRequires: lcov
index c12a6a9a1b7646e9c9501acd4e71f574bb223c13..31040348e63fc048044d220feb064e271ac11ba8 100644 (file)
@@ -17,6 +17,7 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_UNIFIED} PUBLIC
   TPK_INSTALLER_DEPS
   WGT_INSTALLER_DEPS
   RPK_INSTALLER_DEPS
+  LIBXML_DEPS
 )
 
 # Target
index 775d7392509425df680de60cc9df73efb6b84a20..cebdbfd865d1b08fb48cac110743cd718aea5b83 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "unified/unified_installer_factory.h"
 
+#include <libxml/xmlreader.h>
 #include <unzip.h>
 
 #include <boost/filesystem/path.hpp>
@@ -32,6 +33,11 @@ std::map<const char*, const char*> kTypeMap = {
   {"tizen-manifest.xml", "tpk"},
 };
 
+constexpr char kManifestKey[] = "manifest";
+constexpr char kType[] = "type";
+constexpr char kRpkTypeStr[] = "rpk";
+constexpr char kResType[] = "res-type";
+
 std::string ValidatePkgType(const std::string& type) {
   if (type == "tpk" || type == "wgt" || type == "rpk")
     return type;
@@ -80,12 +86,97 @@ std::string GetPkgTypeFromFilename(const boost::filesystem::path& name) {
   return ValidatePkgType(token);
 }
 
+int MoveToChildElement(xmlTextReaderPtr reader, int depth) {
+  int ret = xmlTextReaderRead(reader);
+  int cur = xmlTextReaderDepth(reader);
+
+  while (ret == 1) {
+    switch (xmlTextReaderNodeType(reader)) {
+    case XML_READER_TYPE_ELEMENT:
+      if (cur == depth + 1)
+        return 1;
+      break;
+    case XML_READER_TYPE_TEXT:
+      if (cur == depth + 1)
+        return 0;
+      break;
+    case XML_READER_TYPE_END_ELEMENT:
+      if (cur == depth)
+        return 0;
+      break;
+    default:
+      if (cur <= depth)
+        return 0;
+      break;
+    }
+
+    ret = xmlTextReaderRead(reader);
+    cur = xmlTextReaderDepth(reader);
+  }
+
+  return ret;
+}
+
+std::string GetPkgTypeFromXml(const std::string& info, uid_t uid,
+    bool is_preload) {
+  boost::filesystem::path xml_path =
+      boost::filesystem::path(getUserManifestPath(uid, is_preload))
+      / boost::filesystem::path(info);
+  xml_path += ".xml";
+
+  if (!boost::filesystem::exists(xml_path)) {
+    LOG(ERROR) << "xml path [" << xml_path << "] is not exist";
+    return "";
+  }
+
+  const xmlChar* node;
+  xmlTextReaderPtr reader;
+  xmlChar* tmp = nullptr;
+
+  reader = xmlReaderForFile(xml_path.c_str(), nullptr, 0);
+
+  if (!reader) {
+    LOG(ERROR) << "xmlReaderForFile value is NULL";
+    return {};
+  }
+  std::unique_ptr<xmlTextReader, decltype(xmlFreeTextReader)*> reader_auto(
+      reader, xmlFreeTextReader);
+
+  if (!MoveToChildElement(reader_auto.get(), -1))
+    return {};
+
+  node = xmlTextReaderConstName(reader_auto.get());
+  if (!node) {
+    LOG(ERROR) << "xmlTextReaderConstName value is NULL";
+    return {};
+  }
+
+  if (!strcmp(reinterpret_cast<const char*>(node), kManifestKey)) {
+    tmp = xmlTextReaderGetAttribute(reader_auto.get(),
+        reinterpret_cast<const xmlChar*>(kType));
+    if (tmp) {
+      std::string ret = reinterpret_cast<const char*>(tmp);
+      xmlFree(tmp);
+      return ValidatePkgType(ret);
+    }
+
+    tmp = xmlTextReaderGetAttribute(reader_auto.get(),
+        reinterpret_cast<const xmlChar*>(kResType));
+    if (tmp) {
+      xmlFree(tmp);
+      return kRpkTypeStr;
+    }
+  }
+
+  return {};
+}
+
 }  // namespace
 
 namespace common_installer {
 
 std::string UnifiedInstallerFactory::GetPkgType(
-    const std::string& info, uid_t uid) {
+    const std::string& info, uid_t uid, bool is_preload) {
   std::string type;
   type = GetPkgTypeFromPkgid(info, uid);
 
@@ -100,13 +191,17 @@ std::string UnifiedInstallerFactory::GetPkgType(
       type.clear();
   }
 
+  if (type.empty()) {
+    type = GetPkgTypeFromXml(info, uid, is_preload);
+  }
+
   return type;
 }
 
 std::unique_ptr<AppInstaller> UnifiedInstallerFactory::CreateInstaller(
     PkgMgrPtr pkgmgr, int idx) {
   std::string type = GetPkgType(pkgmgr->GetRequestInfo(idx),
-      pkgmgr->GetUid());
+      pkgmgr->GetUid(), pkgmgr->GetIsPreloadRequest());
 
   if (type.empty()) {
     LOG(ERROR) << "Failed to identify package type, input : "
index c05d0dd8f58b9d6c51455a318979b3c47fc58590..69cc0d938bbe09c19988f2131a598458ee55bec3 100644 (file)
@@ -20,7 +20,7 @@ class UnifiedInstallerFactory : public InstallerFactory {
   std::unique_ptr<AppInstaller> CreateInstaller(PkgMgrPtr pkgmgr, int idx);
 
  private:
-  std::string GetPkgType(const std::string& info, uid_t uid);
+  std::string GetPkgType(const std::string& info, uid_t uid, bool is_preload);
 };
 
 }  // namespace common_installer