#include "unified/unified_installer_factory.h"
+#include <libxml/xmlreader.h>
#include <unzip.h>
#include <boost/filesystem/path.hpp>
{"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;
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);
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 : "