Fix icon copying 59/57259/4 accepted/tizen/mobile/20160122.032617 accepted/tizen/tv/20160122.032703 accepted/tizen/wearable/20160122.032713 submit/tizen/20160120.112210
authorTomasz Iwanek <t.iwanek@samsung.com>
Mon, 18 Jan 2016 10:31:05 +0000 (11:31 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Tue, 19 Jan 2016 16:10:32 +0000 (17:10 +0100)
Icons element are receiving full path in StepParse from now
for both wgt and tpk backend and all modes.

Steps:
 - StepCreateIcons
 - StepBackupIcons
 - StepRecoverIcons
 - StepRemoveIcons
handles icon files only outside package directory (those in: $HOME/.applications/icons/*)
Icons within application directories are copied together with whole package directory (StepCopy)
and are not managed by those steps.

To handle copying icons within package directory new steps are introduced:
 - StepWgtPatchIcons (copy to $package/shared/res/ from widget content directory)
 - StepTpkPatchIcons (copy to $package/shared/res/ if they are in different location, e.g. preload apps)

Following changes needs to be submitted together:
 - https://review.tizen.org/gerrit/57258 (wgt-backend)
 - https://review.tizen.org/gerrit/57257 (app-installers)
 - https://review.tizen.org/gerrit/57259 (tpk-backend)

Verify by:
 $ /usr/bin/tpk-backend-ut/smoke_test --gtest_filter=SmokeTest.UpdateMode_Tpk
 $ /usr/bin/tpk-backend-ut/smoke_test --gtest_filter=SmokeTest.InstallationMode_Tpk
 $ /usr/bin/tpk-backend-ut/smoke_test --gtest_filter=SmokeTest.DeltaMode_Tpk
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.InstallationMode
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.UpdateMode
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.RDSMode
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.DeltaMode
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.UpdateMode_Rollback
 $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.InstallationMode_Rollback

Change-Id: Ib4d9c86f76b4308eb4258cef1882cc8fe79965fb

src/tpk/CMakeLists.txt
src/tpk/step/step_convert_xml.cc
src/tpk/step/step_convert_xml.h
src/tpk/step/step_parse.cc
src/tpk/step/step_parse.h
src/tpk/step/step_tpk_patch_icons.cc [new file with mode: 0644]
src/tpk/step/step_tpk_patch_icons.h [new file with mode: 0644]
src/tpk/tpk_installer.cc

index f57dc43..746517f 100644 (file)
@@ -4,6 +4,7 @@ SET(SRCS
     step/step_parse.cc
     step/step_parse_recovery.cc
     step/step_convert_xml.cc
+    step/step_tpk_patch_icons.cc
     tpk_app_query_interface.cc
     tpk_installer.cc
 )
index 3ce735c..1810cf4 100644 (file)
@@ -31,10 +31,10 @@ const char kXmlXPathAppExpr[] =
 
 }  // namespace
 
-namespace common_installer {
 namespace tpk {
+namespace pkgmgr {
 
-Step::Status StepConvertXml::precheck() {
+common_installer::Step::Status StepConvertXml::precheck() {
   bf::path xml_path = context_->pkg_path.get();
   xml_path /= "tizen-manifest.xml";
 
@@ -78,7 +78,7 @@ bool StepConvertXml::ConvertXml(xmlDocPtr doc) {
   return true;
 }
 
-Step::Status StepConvertXml::process() {
+common_installer::Step::Status StepConvertXml::process() {
   xmlDocPtr doc = xmlParseFile(xml_path_.string().c_str());
   if (!doc) {
     LOG(ERROR) << "Failed to parse xml file";
@@ -110,11 +110,11 @@ Step::Status StepConvertXml::process() {
   return Step::Status::OK;
 }
 
-Step::Status StepConvertXml::clean() {
+common_installer::Step::Status StepConvertXml::clean() {
   return Step::Status::OK;
 }
 
-Step::Status StepConvertXml::undo() {
+common_installer::Step::Status StepConvertXml::undo() {
   bs::error_code error;
 
   if (bf::exists(context_->xml_path.get()))
@@ -123,5 +123,5 @@ Step::Status StepConvertXml::undo() {
   return Step::Status::OK;
 }
 
+}  // namespace pkgmgr
 }  // namespace tpk
-}  // namespace common_installer
index 273b1c7..8a215a6 100644 (file)
@@ -12,8 +12,8 @@
 
 #include <common/step/step.h>
 
-namespace common_installer {
 namespace tpk {
+namespace pkgmgr {
 
 class StepConvertXml : public common_installer::Step {
  public:
@@ -31,7 +31,7 @@ class StepConvertXml : public common_installer::Step {
   SCOPE_LOG_TAG(ConvertXml)
 };
 
+}  // namespace pkgmgr
 }  // namespace tpk
-}  // namespace common_installer
 
 #endif  // TPK_STEP_STEP_CONVERT_XML_H_
index 6f57cce..f3ab7ff 100644 (file)
@@ -75,61 +75,6 @@ common_installer::Step::Status StepParse::precheck() {
   return common_installer::Step::Status::OK;
 }
 
-// TODO(jungh.yeon) : this function should be re-considered
-bf::path StepParse::FindIcon(const std::string& filename) {
-  bf::path icon_path;
-  bf::path app_path;
-
-  if (filename.length() == 0)
-    return icon_path;
-
-  if (index(filename.c_str(), '/'))
-    return filename;
-
-  // FIXME: icons for preloaded apps should also be moved to "shared/res"
-  icon_path = bf::path(getIconPath(context_->uid.get())) / filename;
-  if (access(icon_path.c_str(), F_OK) == 0)
-    return icon_path;
-
-  icon_path = bf::path(getIconPath(context_->uid.get()) /
-              bf::path("default/small") / filename);
-  if (bf::exists(icon_path))
-    return icon_path;
-
-  if (context_->uid.get() == GLOBAL_USER) {
-    app_path = tzplatform_getenv(TZ_SYS_RW_APP);
-  } else {
-    tzplatform_set_user(context_->uid.get());
-    app_path = tzplatform_getenv(TZ_USER_APP);
-    tzplatform_reset_user();
-  }
-
-  icon_path =
-      context_->unpacked_dir_path.get() / bf::path("shared/res") / filename;
-  if (bf::exists(icon_path)) {
-    icon_path =
-        app_path / context_->pkgid.get() / bf::path("shared/res") / filename;
-    return icon_path;
-  }
-
-  icon_path =
-      context_->unpacked_dir_path.get() / bf::path("res/icons") / filename;
-  if (bf::exists(icon_path)) {
-    icon_path =
-        app_path / context_->pkgid.get() / bf::path("res/icons") / filename;
-    return icon_path;
-  }
-
-  icon_path = context_->unpacked_dir_path.get() / filename;
-  if (bf::exists(icon_path)) {
-    icon_path = app_path / context_->pkgid.get() / filename;
-    return icon_path;
-  }
-
-  icon_path = "";
-  return icon_path;
-}
-
 bool StepParse::LocateConfigFile() {
   boost::filesystem::path manifest;
   if (!context_->xml_path.get().empty()) {
@@ -528,7 +473,9 @@ bool StepParse::FillApplicationIconPaths(application_x* app,
     // NOTE: name is an attribute, but the xml writer uses it as text.
     // This must be fixed in whole app-installer modules, including wgt.
     // Current implementation is just for compatibility.
-    icon->text = strdup(FindIcon(application_icon.path()).c_str());
+    bf::path text = context_->root_application_path.get()
+        / context_->pkgid.get() / "shared" / "res" / application_icon.path();
+    icon->text = strdup(text.c_str());
     icon->name = strdup(application_icon.path().c_str());
     icon->lang = strdup(DEFAULT_LOCALE);
     app->icon = g_list_append(app->icon, icon);
index 6ec52a1..e60b6ca 100644 (file)
@@ -42,7 +42,6 @@ class StepParse : public common_installer::Step {
   boost::filesystem::path path_;
 
  private:
-  boost::filesystem::path FindIcon(const std::string& filename);
   bool FillInstallationInfo(manifest_x* manifest);
   bool FillPackageInfo(manifest_x* manifest);
   bool FillAuthorInfo(manifest_x* manifest);
diff --git a/src/tpk/step/step_tpk_patch_icons.cc b/src/tpk/step/step_tpk_patch_icons.cc
new file mode 100644 (file)
index 0000000..756ca71
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "tpk/step/step_tpk_patch_icons.h"
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/system/error_code.hpp>
+#include <common/utils/file_util.h>
+#include <common/utils/glist_range.h>
+#include <pkgmgr-info.h>
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace {
+
+// This function checks for alternative locations of icon file of tpk package
+bf::path LocateIcon(const bf::path& filename, const std::string& pkgid,
+                    const bf::path& root_path, uid_t uid) {
+  std::vector<bf::path> locations;
+  // FIXME: icons for preloaded apps should also be moved to "shared/res"
+  bf::path system_location = bf::path(getIconPath(uid)) / filename;
+  bf::path small_system_location =
+      bf::path(getIconPath(uid)) / "default" / "small" / filename;
+  bf::path res_icons_location = root_path / pkgid / "res" / "icons" / filename;
+
+  locations.push_back(system_location);
+  locations.push_back(small_system_location);
+  locations.push_back(res_icons_location);
+
+  for (auto& location : locations) {
+    if (bf::exists(location)) {
+      return location;
+    }
+  }
+  return {};
+}
+
+}  // namespace
+
+namespace tpk {
+namespace filesystem {
+
+common_installer::Step::Status StepTpkPatchIcons::process() {
+  bf::path common_icon_location = context_->pkg_path.get() / "shared" / "res";
+  bs::error_code error;
+  bf::create_directories(common_icon_location, error);
+  for (application_x* app :
+      GListRange<application_x*>(context_->manifest_data.get()->application)) {
+    if (strcmp(app->type, "capp") != 0)
+      continue;
+    if (app->icon) {
+      icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
+      bf::path icon_text(icon->text);
+      if (!bf::exists(icon->text)) {
+        bf::path source = LocateIcon(icon_text.filename(),
+                                     context_->pkgid.get(),
+                                     context_->root_application_path.get(),
+                                     context_->uid.get());
+        if (!source.empty()) {
+          LOG(DEBUG) << "Fix location of icon: " << source << " to: "
+                     << icon_text;
+          if (!common_installer::CopyFile(source, icon_text)) {
+            return Status::ICON_ERROR;
+          }
+        }
+      }
+    }
+  }
+  return Status::OK;
+}
+
+}  // namespace filesystem
+}  // namespace tpk
diff --git a/src/tpk/step/step_tpk_patch_icons.h b/src/tpk/step/step_tpk_patch_icons.h
new file mode 100644 (file)
index 0000000..10fd3c2
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef TPK_STEP_STEP_TPK_PATCH_ICONS_H_
+#define TPK_STEP_STEP_TPK_PATCH_ICONS_H_
+
+#include <common/step/step.h>
+#include <manifest_parser/utils/logging.h>
+
+namespace tpk {
+namespace filesystem {
+
+/**
+ * @brief The StepTpkPatchIcons class
+ *        Fixes location of icons for tpk apps if icons are not located in
+ *        "shared/res/" directory.
+ */
+class StepTpkPatchIcons : public common_installer::Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; }
+  Status undo() override { return Status::OK; }
+  Status precheck() override { return Status::OK; }
+
+  SCOPE_LOG_TAG(TpkPatchIcons)
+};
+
+}  // namespace filesystem
+}  // namespace tpk
+
+#endif  // TPK_STEP_STEP_TPK_PATCH_ICONS_H_
index 2ca527f..239def4 100644 (file)
@@ -1,5 +1,6 @@
 /* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */
 #include "tpk/tpk_installer.h"
+
 #include <common/app_installer.h>
 #include <common/step/step_configure.h>
 #include <common/step/step_backup_icons.h>
@@ -9,6 +10,7 @@
 #include <common/step/step_copy.h>
 #include <common/step/step_copy_tep.h>
 #include <common/step/step_copy_backup.h>
+#include <common/step/step_copy_storage_directories.h>
 #include <common/step/step_check_old_certificate.h>
 #include <common/step/step_delta_patch.h>
 #include <common/step/step_fail.h>
@@ -42,6 +44,7 @@
 #include "tpk/step/step_parse.h"
 #include "tpk/step/step_parse_recovery.h"
 #include "tpk/step/step_convert_xml.h"
+#include "tpk/step/step_tpk_patch_icons.h"
 
 namespace ci = common_installer;
 
@@ -105,9 +108,10 @@ void TpkInstaller::InstallSteps() {
   AddStep<ci::filesystem::StepCopyTep>();
   AddStep<ci::filesystem::StepCreateStorageDirectories>();
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+  AddStep<tpk::filesystem::StepTpkPatchIcons>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepRegisterSecurity>();
-  AddStep<ci::tpk::StepConvertXml>();
+  AddStep<tpk::pkgmgr::StepConvertXml>();
   AddStep<ci::pkgmgr::StepRegisterApplication>();
 }
 
@@ -125,12 +129,12 @@ void TpkInstaller::UpdateSteps() {
   AddStep<ci::backup::StepBackupIcons>();
   AddStep<ci::backup::StepCopyBackup>();
   AddStep<ci::filesystem::StepCopyTep>();
-  AddStep<ci::filesystem::StepCreateStorageDirectories>();
-  // TODO(t.iwanek): handle coping storage directories
+  AddStep<ci::filesystem::StepCopyStorageDirectories>();
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+  AddStep<tpk::filesystem::StepTpkPatchIcons>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepUpdateSecurity>();
-  AddStep<ci::tpk::StepConvertXml>();
+  AddStep<tpk::pkgmgr::StepConvertXml>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   /* TODO(jungh.yeon): this temporary step will be removed
   * when secondary parsing procedure has removed*/
@@ -167,12 +171,12 @@ void TpkInstaller::DeltaSteps() {
   AddStep<ci::backup::StepBackupManifest>();
   AddStep<ci::backup::StepBackupIcons>();
   AddStep<ci::backup::StepCopyBackup>();
-  AddStep<ci::filesystem::StepCreateStorageDirectories>();
-  // TODO(t.iwanek): handle coping storage directories
+  AddStep<ci::filesystem::StepCopyStorageDirectories>();
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+  AddStep<tpk::filesystem::StepTpkPatchIcons>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepUpdateSecurity>();
-  AddStep<ci::tpk::StepConvertXml>();
+  AddStep<tpk::pkgmgr::StepConvertXml>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
 }
 
@@ -210,6 +214,4 @@ void TpkInstaller::ManifestDirectUpdateSteps() {
   AddStep<ci::pkgmgr::StepUpdateApplication>();
 }
 
-
 }  // namespace tpk
-