Fix tpk lib to extract manifest and icon only 74/108474/2
authorSangyoon Jang <s89.jang@samsung.com>
Wed, 4 Jan 2017 11:23:25 +0000 (20:23 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Wed, 4 Jan 2017 11:43:58 +0000 (20:43 +0900)
Extracting shared/res dir can cause memory issue.
Instead of extracting shared/res dir, tpk lib will find icon file from
manifest and extract icon file only.

Change-Id: I18750638a18a4451d02bd3bdbfda859f49d4c5d5
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
src/lib/tpk_archive_info.cc

index 2d2433f..c34fab8 100644 (file)
@@ -36,17 +36,14 @@ namespace ci = common_installer;
 namespace {
 
 const char kVconfLanguageKey[] = "db/menu_widget/language";
-const std::vector<std::string> kEntries = {
-  "shared/res",
-  "tizen-manifest.xml"
-};
-
-bool ExtractPackageArchive(const char* file_path, const bf::path& tmp_dir) {
-  for (auto& entry : kEntries) {
-    if (!ci::ExtractToTmpDir(file_path, tmp_dir, entry)) {
-      LOG(ERROR) << "Failed to extract";
-      return false;
-    }
+const char kManifestFileName[] = "tizen-manifest.xml";
+const char kSharedResDir[] = "shared/res";
+
+bool ExtractPackageArchive(const char* archive_path, const char* file,
+    const bf::path& tmp_dir) {
+  if (!ci::ExtractToTmpDir(archive_path, tmp_dir, file)) {
+    LOG(ERROR) << "Failed to extract";
+    return false;
   }
   return true;
 }
@@ -209,11 +206,7 @@ bool GetDescriptionInfo(const tpk::parse::TPKConfigParser& parser,
 
 bool ReadIcon(const bf::path& icon, const bf::path& tmp_dir,
     package_manager_pkg_detail_info_t* info) {
-  bf::path icon_path;
-  if (icon.is_absolute())
-    icon_path = icon;
-  else
-    icon_path = tmp_dir / "shared/res" / icon;
+  bf::path icon_path = tmp_dir / icon;
 
   LOG(INFO) << "Icon file path: " << icon_path;
 
@@ -238,41 +231,45 @@ bool ReadIcon(const bf::path& icon, const bf::path& tmp_dir,
 }
 
 template <typename T>
-bool GetAppIcon(const tpk::parse::TPKConfigParser& parser,
-    const std::string& key, const char* locale, const bf::path tmp_dir,
-    package_manager_pkg_detail_info_t* info) {
+std::string GetAppIcon(const tpk::parse::TPKConfigParser& parser,
+    const std::string& key, const char* locale) {
   auto apps = std::static_pointer_cast<const T>(parser.GetManifestData(key));
   if (!apps)
-    return false;
+    return {};
   for (auto& icon : apps->items[0].app_icons.icons()) {
     if (icon.lang().empty())
       continue;
     if (!strcmp(icon.lang().c_str(), locale))
-      return ReadIcon(bf::path(icon.path()), tmp_dir, info);
+      return std::string(icon.path());
   }
   for (auto& icon : apps->items[0].app_icons.icons()) {
     if (icon.lang().empty())
-      return ReadIcon(bf::path(icon.path()), tmp_dir, info);
+      return std::string(icon.path());
   }
-  return false;
+  return {};
 }
 
-bool GetIconInfo(const tpk::parse::TPKConfigParser& parser, const char* locale,
-    const bf::path tmp_dir, package_manager_pkg_detail_info_t* info) {
+std::string GetIconInfo(const tpk::parse::TPKConfigParser& parser,
+    const char* locale) {
   // get icon from ui application
-  if (GetAppIcon<tpk::parse::UIApplicationInfoList>(parser,
-      tpk::application_keys::kUIApplicationKey, locale, tmp_dir, info))
-    return true;
-  if (GetAppIcon<tpk::parse::ServiceApplicationInfoList>(parser,
-      tpk::application_keys::kServiceApplicationKey, locale, tmp_dir, info))
-    return true;
-  if (GetAppIcon<tpk::parse::WidgetApplicationInfoList>(parser,
-      tpk::application_keys::kWidgetApplicationKey, locale, tmp_dir, info))
-    return true;
-  if (GetAppIcon<tpk::parse::WatchApplicationInfoList>(parser,
-      tpk::application_keys::kWatchApplicationKey, locale, tmp_dir, info))
-    return true;
-  return false;
+  std::string icon;
+  icon = GetAppIcon<tpk::parse::UIApplicationInfoList>(parser,
+      tpk::application_keys::kUIApplicationKey, locale);
+  if (!icon.empty())
+    return icon;
+  icon = GetAppIcon<tpk::parse::ServiceApplicationInfoList>(parser,
+      tpk::application_keys::kServiceApplicationKey, locale);
+  if (!icon.empty())
+    return icon;
+  icon = GetAppIcon<tpk::parse::WidgetApplicationInfoList>(parser,
+      tpk::application_keys::kWidgetApplicationKey, locale);
+  if (!icon.empty())
+    return icon;
+  icon = GetAppIcon<tpk::parse::WatchApplicationInfoList>(parser,
+      tpk::application_keys::kWatchApplicationKey, locale);
+  if (!icon.empty())
+    return icon;
+  return {};
 }
 
 }  // namespace
@@ -283,11 +280,11 @@ bool TpkArchiveInfo::GetArchiveInfo(const char* file_path,
   if (!ci::CreateDir(tmp_dir))
     return false;
   LOG(DEBUG) << "Unpack at temporary dir: " << tmp_dir;
-  if (!ExtractPackageArchive(file_path, tmp_dir))
+  if (!ExtractPackageArchive(file_path, kManifestFileName, tmp_dir))
     return false;
 
   tpk::parse::TPKConfigParser parser;
-  bf::path manifest_path = tmp_dir / "tizen-manifest.xml";
+  bf::path manifest_path = tmp_dir / kManifestFileName;
   if (!parser.ParseManifest(manifest_path)) {
     LOG(ERROR) << "Failed to parse";
     return false;
@@ -309,8 +306,16 @@ bool TpkArchiveInfo::GetArchiveInfo(const char* file_path,
     LOG(WARNING) << "Failed to get label info";
   if (!GetDescriptionInfo(parser, locale, info))
     LOG(WARNING) << "Failed to get description info";
-  if (!GetIconInfo(parser, locale, tmp_dir, info))
-    LOG(WARNING) << "Failed to get icon info";
+  std::string icon = GetIconInfo(parser, locale);
+  if (!icon.empty()) {
+    bf::path icon_path = bf::path(kSharedResDir) / icon;
+    if (!ExtractPackageArchive(file_path, icon_path.string().c_str(), tmp_dir))
+      return false;
+    if (!ReadIcon(icon_path, tmp_dir, info)) {
+      LOG(WARNING) << "Failed to get icon info";
+      return false;
+    }
+  }
 
   free(locale);
   bf::remove_all(tmp_dir);