Implement hybrid webapplication installation 81/56581/8 accepted/tizen/mobile/20160115.010738 accepted/tizen/mobile/20160115.010921 accepted/tizen/tv/20160115.010750 accepted/tizen/tv/20160115.010934 accepted/tizen/wearable/20160115.010809 accepted/tizen/wearable/20160115.010955 submit/tizen/20160114.141522 submit/tizen/20160114.224350
authorTomasz Iwanek <t.iwanek@samsung.com>
Fri, 8 Jan 2016 11:32:18 +0000 (12:32 +0100)
committerPawel Sikorski <p.sikorski@samsung.com>
Thu, 14 Jan 2016 13:07:07 +0000 (05:07 -0800)
Implemenation of hybrid package installation uses both
tpk and wgt steps, composing information from tizen
manifest file and w3c config.xml file. Installation
of hybrid has different flow so there is new installer
class introduced to avoid branching in steps. Instead
there is "hacky" branch in wgt-backend main() to choose
which step sequence to choose.

Requires:
 - https://review.tizen.org/gerrit/56503
 - https://review.tizen.org/gerrit/56506
 - https://review.tizen.org/gerrit/56795
 - https://review.tizen.org/gerrit/56918
 - https://review.tizen.org/gerrit/56920
 - https://review.tizen.org/gerrit/56921
 - https://review.tizen.org/gerrit/56724

Graph of targets (dependencies) changed to following:
  common_lib <-- tpk_lib
  common_lib <-- wgt_lib
  tpk_lib    <-- hybrid_lib
  wgt_lib    <-- hybrid_lib
  wgt_lib    <-- wgt_backend
  hybrid_lib <-- wgt_backend
  tpk_lib    <-- tpk_backend

Recovery for hybrid package will be added later
if possible.

Change-Id: I433f6030630f47c9f49025d89e267e5912bc78d9

26 files changed:
CMakeLists.txt
packaging/wgt-backend.spec
src/CMakeLists.txt
src/hybrid/CMakeLists.txt [new file with mode: 0644]
src/hybrid/hybrid_backend_data.h [new file with mode: 0644]
src/hybrid/hybrid_installer.cc [new file with mode: 0644]
src/hybrid/hybrid_installer.h [new file with mode: 0644]
src/hybrid/step/step_encrypt_resources.cc [new file with mode: 0644]
src/hybrid/step/step_encrypt_resources.h [new file with mode: 0644]
src/hybrid/step/step_merge_tpk_config.cc [new file with mode: 0644]
src/hybrid/step/step_merge_tpk_config.h [new file with mode: 0644]
src/hybrid/step/step_parse.cc [new file with mode: 0644]
src/hybrid/step/step_parse.h [new file with mode: 0644]
src/hybrid/step/step_stash_tpk_config.cc [new file with mode: 0644]
src/hybrid/step/step_stash_tpk_config.h [new file with mode: 0644]
src/wgt/CMakeLists.txt
src/wgt/step/step_create_symbolic_link.cc
src/wgt/step/step_encrypt_resources.cc
src/wgt/step/step_encrypt_resources.h
src/wgt/step/step_parse.cc
src/wgt/step/step_parse.h
src/wgt/wgt_app_query_interface.cc
src/wgt/wgt_app_query_interface.h
src/wgt/wgt_installer.cc
src/wgt_backend/CMakeLists.txt [new file with mode: 0644]
src/wgt_backend/wgt_backend.cc [moved from src/wgt/wgt_backend.cc with 56% similarity]

index 565d531..b9a8224 100644 (file)
@@ -25,6 +25,7 @@ SET(CMAKE_CXX_FLAGS_CCOV       "-O0 -std=c++11 -g --coverage")
 SET(TARGET_LIBNAME_WGT "wgt-installer")
 SET(TARGET_WGT_BACKEND "wgt-backend")
 SET(TARGET_SMOKE_TEST "smoke_test")
+SET(TARGET_LIBNAME_HYBRID "hybrid-installer")
 
 ADD_DEFINITIONS("-Wall")
 ADD_DEFINITIONS("-Wextra")
@@ -41,6 +42,7 @@ PKG_CHECK_MODULES(MANIFEST_HANDLERS_DEPS REQUIRED manifest-handlers)
 PKG_CHECK_MODULES(MANIFEST_PARSER_DEPS REQUIRED manifest-parser)
 PKG_CHECK_MODULES(PKGMGR_INSTALLER_DEPS REQUIRED pkgmgr-installer)
 PKG_CHECK_MODULES(ENCRYPTION_DEPS REQUIRED libwebappenc)
+PKG_CHECK_MODULES(TPK_INSTALLER_DEPS REQUIRED tpk-installer)
 
 FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem regex program_options)
 FIND_PACKAGE(GTest REQUIRED)
index 9c001e1..fadbca2 100644 (file)
@@ -20,6 +20,7 @@ BuildRequires:  pkgconfig(manifest-parser)
 BuildRequires:  pkgconfig(manifest-handlers)
 BuildRequires:  pkgconfig(pkgmgr-installer)
 BuildRequires:  pkgconfig(libwebappenc)
+BuildRequires:  pkgconfig(tpk-installer)
 
 %description
 This is a package that installs the WGT backend of pkgmgr.
index f0e3653..0136fd6 100644 (file)
@@ -1,2 +1,4 @@
+ADD_SUBDIRECTORY(hybrid)
 ADD_SUBDIRECTORY(wgt)
+ADD_SUBDIRECTORY(wgt_backend)
 ADD_SUBDIRECTORY(unit_tests)
diff --git a/src/hybrid/CMakeLists.txt b/src/hybrid/CMakeLists.txt
new file mode 100644 (file)
index 0000000..040d9fc
--- /dev/null
@@ -0,0 +1,19 @@
+SET(SRCS
+  step/step_encrypt_resources.cc
+  step/step_merge_tpk_config.cc
+  step/step_parse.cc
+  step/step_stash_tpk_config.cc
+  hybrid_installer.cc
+)
+ADD_LIBRARY(${TARGET_LIBNAME_HYBRID} STATIC ${SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_LIBNAME_HYBRID} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
+
+# Target - deps
+APPLY_PKG_CONFIG(${TARGET_LIBNAME_HYBRID} PUBLIC
+  TPK_INSTALLER_DEPS
+  Boost
+)
+
+# Target - in-package deps
+TARGET_LINK_LIBRARIES(${TARGET_LIBNAME_HYBRID} PRIVATE ${TARGET_LIBNAME_WGT})
diff --git a/src/hybrid/hybrid_backend_data.h b/src/hybrid/hybrid_backend_data.h
new file mode 100644 (file)
index 0000000..c3a7d8b
--- /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 HYBRID_HYBRID_BACKEND_DATA_H_
+#define HYBRID_HYBRID_BACKEND_DATA_H_
+
+#include <common/utils/property.h>
+#include <manifest_handlers/setting_handler.h>
+#include <pkgmgrinfo_basic.h>
+#include <pkgmgr_parser.h>
+
+#include <string>
+#include <vector>
+
+#include "wgt/wgt_backend_data.h"
+
+namespace hybrid {
+
+class HybridBackendData : public wgt::WgtBackendData {
+ public:
+  HybridBackendData() { }
+  ~HybridBackendData() override {
+    if (tpk_manifest_data.get())
+      pkgmgr_parser_free_manifest_xml(tpk_manifest_data.get());
+  }
+
+  Property<manifest_x*> tpk_manifest_data;
+};
+
+}  // namespace hybrid
+
+#endif  // HYBRID_HYBRID_BACKEND_DATA_H_
+
diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc
new file mode 100644 (file)
index 0000000..7e75a28
--- /dev/null
@@ -0,0 +1,168 @@
+// 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 "hybrid/hybrid_installer.h"
+
+#include <common/step/step_check_signature.h>
+#include <common/step/step_backup_icons.h>
+#include <common/step/step_backup_manifest.h>
+#include <common/step/step_configure.h>
+#include <common/step/step_copy.h>
+#include <common/step/step_copy_backup.h>
+#include <common/step/step_create_icons.h>
+#include <common/step/step_delta_patch.h>
+#include <common/step/step_fail.h>
+#include <common/step/step_kill_apps.h>
+#include <common/step/step_old_manifest.h>
+#include <common/step/step_parse.h>
+#include <common/step/step_privilege_compatibility.h>
+#include <common/step/step_register_app.h>
+#include <common/step/step_register_security.h>
+#include <common/step/step_remove_files.h>
+#include <common/step/step_remove_icons.h>
+#include <common/step/step_revoke_security.h>
+#include <common/step/step_rollback_deinstallation_security.h>
+#include <common/step/step_rollback_installation_security.h>
+#include <common/step/step_unregister_app.h>
+#include <common/step/step_unzip.h>
+#include <common/step/step_update_app.h>
+#include <common/step/step_update_security.h>
+
+#include <tpk/step/step_create_symbolic_link.h>
+#include <tpk/step/step_parse.h>
+
+#include "hybrid/hybrid_backend_data.h"
+#include "hybrid/step/step_encrypt_resources.h"
+#include "hybrid/step/step_merge_tpk_config.h"
+#include "hybrid/step/step_stash_tpk_config.h"
+#include "hybrid/step/step_parse.h"
+#include "wgt/step/step_check_settings_level.h"
+#include "wgt/step/step_check_wgt_background_category.h"
+#include "wgt/step/step_create_symbolic_link.h"
+#include "wgt/step/step_generate_xml.h"
+#include "wgt/step/step_remove_encryption_data.h"
+#include "wgt/step/step_wgt_create_icons.h"
+#include "wgt/step/step_wgt_create_storage_directories.h"
+#include "wgt/step/step_wgt_copy_storage_directories.h"
+
+namespace ci = common_installer;
+
+namespace hybrid {
+
+HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
+    : AppInstaller("wgt", pkgmgr) {
+  context_->backend_data.set(new HybridBackendData());
+
+  switch (pkgmgr_->GetRequestType()) {
+    case ci::RequestType::Install:
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      AddStep<ci::filesystem::StepUnzip>();
+      AddStep<tpk::parse::StepParse>();
+      AddStep<hybrid::parse::StepStashTpkConfig>();
+      AddStep<hybrid::parse::StepParse>(true);
+      AddStep<hybrid::parse::StepMergeTpkConfig>();
+      AddStep<ci::security::StepCheckSignature>();
+      AddStep<ci::security::StepPrivilegeCompatibility>();
+      AddStep<wgt::security::StepCheckSettingsLevel>();
+      AddStep<wgt::security::StepCheckWgtBackgroundCategory>();
+      AddStep<hybrid::encrypt::StepEncryptResources>();
+      AddStep<ci::security::StepRollbackInstallationSecurity>();
+      AddStep<ci::filesystem::StepCopy>();
+      AddStep<wgt::filesystem::StepWgtCreateStorageDirectories>();
+      AddStep<wgt::filesystem::StepCreateSymbolicLink>();
+      AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+      AddStep<ci::filesystem::StepCreateIcons>();
+      AddStep<wgt::filesystem::StepWgtCreateIcons>();
+      AddStep<wgt::pkgmgr::StepGenerateXml>();
+      AddStep<ci::pkgmgr::StepRegisterApplication>();
+      AddStep<ci::security::StepRegisterSecurity>();
+      break;
+    case ci::RequestType::Update:
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      AddStep<ci::filesystem::StepUnzip>();
+      AddStep<tpk::parse::StepParse>();
+      AddStep<hybrid::parse::StepStashTpkConfig>();
+      AddStep<hybrid::parse::StepParse>(true);
+      AddStep<hybrid::parse::StepMergeTpkConfig>();
+      AddStep<ci::security::StepCheckSignature>();
+      AddStep<ci::security::StepPrivilegeCompatibility>();
+      AddStep<wgt::security::StepCheckSettingsLevel>();
+      AddStep<wgt::security::StepCheckWgtBackgroundCategory>();
+      AddStep<hybrid::encrypt::StepEncryptResources>();
+      AddStep<ci::security::StepRollbackInstallationSecurity>();
+      AddStep<ci::backup::StepOldManifest>();
+      AddStep<ci::pkgmgr::StepKillApps>();
+      AddStep<ci::backup::StepBackupManifest>();
+      AddStep<ci::backup::StepBackupIcons>();
+      AddStep<ci::backup::StepCopyBackup>();
+      AddStep<wgt::filesystem::StepWgtCopyStorageDirectories>();
+      AddStep<wgt::filesystem::StepCreateSymbolicLink>();
+      AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+      AddStep<ci::filesystem::StepCreateIcons>();
+      AddStep<wgt::filesystem::StepWgtCreateIcons>();
+      AddStep<ci::security::StepUpdateSecurity>();
+      AddStep<wgt::pkgmgr::StepGenerateXml>();
+      AddStep<ci::pkgmgr::StepUpdateApplication>();
+      break;
+    case ci::RequestType::Uninstall:
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      // TODO(t.iwanek): this parses both configuration files
+      // tpk and wgt, removing pkgmgr-parser should change this code
+      // that it will still support parsing both files
+      AddStep<ci::parse::StepParse>();
+      AddStep<ci::pkgmgr::StepKillApps>();
+      AddStep<ci::backup::StepBackupManifest>();
+      AddStep<ci::pkgmgr::StepUnregisterApplication>();
+      AddStep<ci::security::StepRollbackDeinstallationSecurity>();
+      AddStep<ci::filesystem::StepRemoveFiles>();
+      AddStep<ci::filesystem::StepRemoveIcons>();
+      AddStep<wgt::encrypt::StepRemoveEncryptionData>();
+      AddStep<ci::security::StepRevokeSecurity>();
+      break;
+    case ci::RequestType::Reinstall:
+      // RDS is not supported for hybrid apps
+      AddStep<ci::configuration::StepFail>();
+      break;
+    case ci::RequestType::Delta:
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      AddStep<ci::filesystem::StepUnzip>();
+      // TODO(t.iwanek): manifest is parsed twice...
+      AddStep<tpk::parse::StepParse>();
+      AddStep<hybrid::parse::StepStashTpkConfig>();
+      AddStep<hybrid::parse::StepParse>(false);
+      AddStep<hybrid::parse::StepMergeTpkConfig>();
+      AddStep<ci::filesystem::StepDeltaPatch>();
+      AddStep<wgt::parse::StepParse>(true);
+      AddStep<ci::security::StepCheckSignature>();
+      AddStep<ci::security::StepPrivilegeCompatibility>();
+      AddStep<wgt::security::StepCheckSettingsLevel>();
+      AddStep<wgt::security::StepCheckWgtBackgroundCategory>();
+      AddStep<hybrid::encrypt::StepEncryptResources>();
+      AddStep<ci::security::StepRollbackInstallationSecurity>();
+      AddStep<ci::backup::StepOldManifest>();
+      AddStep<ci::pkgmgr::StepKillApps>();
+      AddStep<ci::backup::StepBackupManifest>();
+      AddStep<ci::backup::StepBackupIcons>();
+      AddStep<ci::backup::StepCopyBackup>();
+      AddStep<wgt::filesystem::StepWgtCopyStorageDirectories>();
+      AddStep<wgt::filesystem::StepCreateSymbolicLink>();
+      AddStep<tpk::filesystem::StepCreateSymbolicLink>();
+      AddStep<ci::filesystem::StepCreateIcons>();
+      AddStep<wgt::filesystem::StepWgtCreateIcons>();
+      AddStep<ci::security::StepUpdateSecurity>();
+      AddStep<wgt::pkgmgr::StepGenerateXml>();
+      AddStep<ci::pkgmgr::StepUpdateApplication>();
+      break;
+    case ci::RequestType::Recovery:
+      // TODO(t.iwanek): implement recovery for hybrid apps if possible
+      AddStep<ci::configuration::StepFail>();
+      break;
+    default:
+      AddStep<ci::configuration::StepFail>();
+      break;
+  }
+}
+
+}  // namespace hybrid
+
diff --git a/src/hybrid/hybrid_installer.h b/src/hybrid/hybrid_installer.h
new file mode 100644 (file)
index 0000000..9824d21
--- /dev/null
@@ -0,0 +1,31 @@
+// 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 HYBRID_HYBRID_INSTALLER_H_
+#define HYBRID_HYBRID_INSTALLER_H_
+
+#include "common/app_installer.h"
+#include "common/pkgmgr_interface.h"
+
+namespace hybrid {
+
+/**
+ * @brief The TpkInstaller class
+ *        Handles request of installation of native part of hybrid package.
+ *
+ * Pkgmgr request is parsed within and sequence of steps is built to be run.
+ *
+ * This backend is called by wgt-backend if it encounters hybrid package to
+ * install native part of that package.
+ */
+class HybridInstaller : public common_installer::AppInstaller {
+ public:
+  explicit HybridInstaller(common_installer::PkgMgrPtr pkgmgr);
+
+  SCOPE_LOG_TAG(HybridInstaller)
+};
+
+}  // namespace hybrid
+
+#endif  // HYBRID_HYBRID_INSTALLER_H_
diff --git a/src/hybrid/step/step_encrypt_resources.cc b/src/hybrid/step/step_encrypt_resources.cc
new file mode 100644 (file)
index 0000000..a4411b6
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 "hybrid/step/step_encrypt_resources.h"
+
+namespace hybrid {
+namespace encrypt {
+
+void StepEncryptResources::SetEncryptionRoot() {
+  input_ = context_->unpacked_dir_path.get() / "res/wgt";
+}
+
+}  // namespace encrypt
+}  // namespace hybrid
+
diff --git a/src/hybrid/step/step_encrypt_resources.h b/src/hybrid/step/step_encrypt_resources.h
new file mode 100644 (file)
index 0000000..c86e510
--- /dev/null
@@ -0,0 +1,33 @@
+// 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 HYBRID_STEP_STEP_ENCRYPT_RESOURCES_H_
+#define HYBRID_STEP_STEP_ENCRYPT_RESOURCES_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "wgt/step/step_encrypt_resources.h"
+
+namespace hybrid {
+namespace encrypt {
+
+/**
+ * \brief Step that encrypt application resources files if flagged to do so
+ *
+ * This is variant for hybrid package
+ */
+class StepEncryptResources : public wgt::encrypt::StepEncryptResources {
+ public:
+  using wgt::encrypt::StepEncryptResources::StepEncryptResources;
+
+ private:
+  void SetEncryptionRoot() override;
+
+  SCOPE_LOG_TAG(EncryptResources)
+};
+
+}  // namespace encrypt
+}  // namespace hybrid
+
+#endif  // HYBRID_STEP_STEP_ENCRYPT_RESOURCES_H_
diff --git a/src/hybrid/step/step_merge_tpk_config.cc b/src/hybrid/step/step_merge_tpk_config.cc
new file mode 100644 (file)
index 0000000..77f8407
--- /dev/null
@@ -0,0 +1,32 @@
+// 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 "hybrid/step/step_merge_tpk_config.h"
+
+#include <pkgmgrinfo_basic.h>
+
+#include "hybrid/hybrid_backend_data.h"
+
+namespace hybrid {
+namespace parse {
+
+common_installer::Step::Status StepMergeTpkConfig::process() {
+  HybridBackendData* data =
+      static_cast<HybridBackendData*>(context_->backend_data.get());
+  manifest_x* tpk_data = data->tpk_manifest_data.get();
+  manifest_x* wgt_data = context_->manifest_data.get();
+
+  wgt_data->application =
+      g_list_concat(wgt_data->application, tpk_data->application);
+  tpk_data->application = nullptr;
+
+  wgt_data->privileges =
+      g_list_concat(wgt_data->privileges, tpk_data->privileges);
+  tpk_data->privileges = nullptr;
+
+  return Status::OK;
+}
+
+}  // namespace parse
+}  // namespace hybrid
diff --git a/src/hybrid/step/step_merge_tpk_config.h b/src/hybrid/step/step_merge_tpk_config.h
new file mode 100644 (file)
index 0000000..e8476ef
--- /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 HYBRID_STEP_STEP_MERGE_TPK_CONFIG_H_
+#define HYBRID_STEP_STEP_MERGE_TPK_CONFIG_H_
+
+#include <common/step/step.h>
+#include <manifest_parser/utils/logging.h>
+
+namespace hybrid {
+namespace parse {
+
+/**
+ * \brief MergeTpkConfig
+ *        Merges information from tpk manifest into information from widget
+ *        configuration for hybrid package.
+ */
+class StepMergeTpkConfig : 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(MergeTpkConfig)
+};
+
+}  // namespace parse
+}  // namespace hybrid
+
+#endif  // HYBRID_STEP_STEP_MERGE_TPK_CONFIG_H_
diff --git a/src/hybrid/step/step_parse.cc b/src/hybrid/step/step_parse.cc
new file mode 100644 (file)
index 0000000..c15fa2a
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 "hybrid/step/step_parse.h"
+
+namespace {
+
+const char kResWgtPath[] = "res/wgt";
+
+}
+
+namespace hybrid {
+namespace parse {
+
+bool StepParse::LocateConfigFile() {
+  return Check(context_->unpacked_dir_path.get() / kResWgtPath);
+}
+
+}  // namespace parse
+}  // namespace hybrid
+
diff --git a/src/hybrid/step/step_parse.h b/src/hybrid/step/step_parse.h
new file mode 100644 (file)
index 0000000..aff8a71
--- /dev/null
@@ -0,0 +1,33 @@
+// 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 HYBRID_STEP_STEP_PARSE_H_
+#define HYBRID_STEP_STEP_PARSE_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "wgt/step/step_parse.h"
+
+namespace hybrid {
+namespace parse {
+
+/**
+ * \brief This step parse config.xml configuration file of widget
+ *
+ * This subclass overrides location of file and it is used when hybrid package
+ * is installed.
+ */
+class StepParse : public wgt::parse::StepParse {
+ public:
+  using wgt::parse::StepParse::StepParse;
+
+  bool LocateConfigFile() override;
+
+  SCOPE_LOG_TAG(Parse)
+};
+
+}  // namespace parse
+}  // namespace hybrid
+
+#endif  // HYBRID_STEP_STEP_PARSE_H_
diff --git a/src/hybrid/step/step_stash_tpk_config.cc b/src/hybrid/step/step_stash_tpk_config.cc
new file mode 100644 (file)
index 0000000..c409a44
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 "hybrid/step/step_stash_tpk_config.h"
+
+#include "hybrid/hybrid_backend_data.h"
+
+namespace hybrid {
+namespace parse {
+
+common_installer::Step::Status StepStashTpkConfig::process() {
+  HybridBackendData* data =
+      static_cast<HybridBackendData*>(context_->backend_data.get());
+  data->tpk_manifest_data.set(context_->manifest_data.get());
+  context_->manifest_data.set(nullptr);
+
+  return Status::OK;
+}
+
+}  // namespace parse
+}  // namespace hybrid
diff --git a/src/hybrid/step/step_stash_tpk_config.h b/src/hybrid/step/step_stash_tpk_config.h
new file mode 100644 (file)
index 0000000..7db654c
--- /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 HYBRID_STEP_STEP_STASH_TPK_CONFIG_H_
+#define HYBRID_STEP_STEP_STASH_TPK_CONFIG_H_
+
+#include <common/step/step.h>
+#include <manifest_parser/utils/logging.h>
+
+namespace hybrid {
+namespace parse {
+
+/**
+ * \brief StepCheckHybrid
+ *        Backups information about parsing tpk manifest file in backend_data
+ *        structure.
+ */
+class StepStashTpkConfig : 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(StashTpkConfig)
+};
+
+}  // namespace parse
+}  // namespace hybrid
+
+#endif  // HYBRID_STEP_STEP_STASH_TPK_CONFIG_H_
index d1201bb..a1ee89c 100644 (file)
@@ -31,10 +31,8 @@ ENDIF(WRT_LAUNCHER)
 
 # Target - definition
 ADD_LIBRARY(${TARGET_LIBNAME_WGT} STATIC ${SRCS})
-ADD_EXECUTABLE(${TARGET_WGT_BACKEND} "wgt_backend.cc")
 # Target - includes
 TARGET_INCLUDE_DIRECTORIES(${TARGET_LIBNAME_WGT} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
-TARGET_INCLUDE_DIRECTORIES(${TARGET_WGT_BACKEND} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
 # Target - deps
 APPLY_PKG_CONFIG(${TARGET_LIBNAME_WGT} PUBLIC
   APP_INSTALLERS_DEPS
@@ -44,10 +42,3 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_WGT} PUBLIC
   ENCRYPTION_DEPS
   Boost
 )
-
-# Target - in-package deps
-TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PRIVATE ${TARGET_LIBNAME_WGT})
-
-# Install
-INSTALL(TARGETS ${TARGET_LIBNAME_WGT} DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(TARGETS ${TARGET_WGT_BACKEND} DESTINATION ${BINDIR})
index 1a3eda2..d8a18e7 100644 (file)
@@ -33,10 +33,11 @@ common_installer::Step::Status StepCreateSymbolicLink::process() {
   boost::system::error_code error;
   for (application_x* app :
        GListRange<application_x*>(context_->manifest_data.get()->application)) {
+    // filter out non-wgt apps as this step is run for hybrid backend too
+    if (strcmp("webapp", app->type) != 0)
+      continue;
     // binary is a symbolic link named <appid> and is located in <pkgid>/<appid>
-    bf::path exec_path =
-        context_->pkg_path.get()
-            / bf::path("bin");
+    bf::path exec_path = context_->pkg_path.get() / bf::path("bin");
     common_installer::CreateDir(exec_path);
 
     exec_path /= bf::path(app->appid);
@@ -52,7 +53,7 @@ common_installer::Step::Status StepCreateSymbolicLink::process() {
       return Step::Status::ERROR;
     }
   }
-  LOG(DEBUG) << "Successfully parse tizen manifest xml";
+  LOG(DEBUG) << "Symlinks created successfully";
 
   return Status::OK;
 }
index 08f659d..51c1aec 100644 (file)
@@ -19,7 +19,6 @@
 #include <set>
 #include <string>
 
-
 namespace {
 
 const std::set<std::string> encryptSet { ".html", ".htm", ".css", ".js"};
@@ -40,7 +39,7 @@ common_installer::Step::Status StepEncryptResources::precheck() {
     return common_installer::Step::Status::ERROR;
   }
 
-  input_ = context_->unpacked_dir_path.get();
+  SetEncryptionRoot();
 
   if (input_.empty()) {
     LOG(ERROR) << "unpacked_dir_path attribute is empty";
@@ -200,6 +199,10 @@ bool StepEncryptResources::EncryptFile(const bf::path &src) {
   return true;
 }
 
+void StepEncryptResources::SetEncryptionRoot() {
+  input_ = context_->unpacked_dir_path.get();
+}
+
 bool StepEncryptResources::ToBeEncrypted(const bf::path &file) {
   size_t found_key = file.string().rfind(".");
   if (std::string::npos != found_key) {
index 2d64a51..d6a8b19 100644 (file)
@@ -53,14 +53,20 @@ class StepEncryptResources : public common_installer::Step {
    */
   Status precheck() override;
 
+ protected:
+  boost::filesystem::path input_;
+
  private:
+  virtual void SetEncryptionRoot();
+
   bool Encrypt(const boost::filesystem::path &src);
   bool EncryptFile(const boost::filesystem::path &src);
   bool ToBeEncrypted(const boost::filesystem::path &file);
   WgtBackendData* backend_data_;
-  boost::filesystem::path input_;
   SCOPE_LOG_TAG(EncryptResources)
 };
+
 }  // namespace encrypt
 }  // namespace wgt
+
 #endif  // WGT_STEP_STEP_ENCRYPT_RESOURCES_H_
index 315a46d..392196e 100644 (file)
@@ -526,7 +526,8 @@ common_installer::Step::Status StepParse::process() {
   if (perm_info)
      permissions = perm_info->GetAPIPermissions();
 
-  std::unique_ptr<WgtBackendData> backend_data(new WgtBackendData());
+  WgtBackendData* backend_data =
+      static_cast<WgtBackendData*>(context_->backend_data.get());
 
   std::shared_ptr<const SettingInfo> settings_info =
       std::static_pointer_cast<const SettingInfo>(
@@ -535,8 +536,6 @@ common_installer::Step::Status StepParse::process() {
   if (settings_info)
     backend_data->settings.set(*settings_info);
 
-  context_->backend_data.set(backend_data.release());
-
   LOG(DEBUG) << " Read data -[ ";
   LOG(DEBUG) << "App id: " << info->id();
   LOG(DEBUG) << "  package     = " <<  info->package();
@@ -553,13 +552,16 @@ common_installer::Step::Status StepParse::process() {
   LOG(DEBUG) << "  ]-";
   LOG(DEBUG) << "]-";
 
+  // TODO(t.iwanek): In delta mode this step is running two times
+  if (context_->manifest_data.get())
+    pkgmgr_parser_free_manifest_xml(context_->manifest_data.get());
+
   context_->manifest_data.set(manifest);
   return common_installer::Step::Status::OK;
 }
 
 bool StepParse::Check(const boost::filesystem::path& widget_path) {
-  boost::filesystem::path config = widget_path;
-  config /= "config.xml";
+  boost::filesystem::path config = widget_path / "config.xml";
 
   LOG(DEBUG) << "config.xml path: " << config;
 
index 115ccf0..e1f2547 100644 (file)
@@ -23,43 +23,16 @@ namespace wgt {
 namespace parse {
 
 /**
- * \brief This step parse manifest.xml document
+ * \brief This step parse config.xml configuration file of widget
  */
 class StepParse : public common_installer::Step {
  public:
-  /**
-   * \brief Explicit constructor
-   *
-   * \param context Installer context
-   * \param check_start_file Flag if start file should be validated
-   */
   explicit StepParse(common_installer::InstallerContext* context,
       bool check_start_file);
 
-  /**
-   * \brief
-   */
   Status process() override;
-
-  /**
-   * \brief Empty method
-   *
-   * \return Status::OK
-   */
   Status clean() override { return Status::OK; }
-
-  /**
-   * \brief Empty method
-   *
-   * \return Status::OK
-   */
   Status undo() override { return Status::OK; }
-
-  /**
-   * \brief Empty method
-   *
-   * \return Status::OK
-   */
   Status precheck() override { return Status::OK; }
 
  protected:
index 2a8e046..3f42f71 100644 (file)
@@ -32,10 +32,14 @@ namespace ci = common_installer;
 
 namespace {
 
-std::string GetInstallationPackagePath(int argc, char** argv) {
+const char kHybridConfigLocation[] = "res/wgt/config.xml";
+const char kTizenManifestLocation[] = "tizen-manifest.xml";
+
+std::string GetInstallationRequestInfo(int argc, char** argv) {
   std::string path;
   for (int i = 0; i < argc; ++i) {
-    if (!strcmp(argv[i], "-i")) {
+    if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "-r") ||
+        !strcmp(argv[i], "-d") || !strcmp(argv[i], "-b")) {
       if (i + 1 < argc) {
         path = argv[i + 1];
         break;
@@ -46,6 +50,8 @@ std::string GetInstallationPackagePath(int argc, char** argv) {
 }
 
 std::string GetPkgIdFromPath(const std::string& path) {
+  if (!bf::exists(path))
+    return {};
   bf::path tmp_path = common_installer::GenerateTmpDir("/tmp");
   bs::error_code code;
   bf::create_directories(tmp_path, code);
@@ -87,15 +93,35 @@ std::string GetPkgIdFromPath(const std::string& path) {
 namespace wgt {
 
 bool WgtAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) {
-  std::string path = GetInstallationPackagePath(argc, argv);
-  if (path.empty()) {
-    // not the installaton
+  std::string path = GetInstallationRequestInfo(argc, argv);
+  if (path.empty())
     return false;
-  }
   std::string pkg_id = GetPkgIdFromPath(path);
   if (pkg_id.empty())
     return false;
   return ci::IsPackageInstalled(pkg_id, ci::GetRequestMode());
 }
 
+bool WgtAppQueryInterface::IsHybridApplication(int argc, char** argv) {
+  std::string arg = GetInstallationRequestInfo(argc, argv);
+  if (ci::IsPackageInstalled(arg, ci::GetRequestMode())) {
+    bf::path package_directory(ci::GetRootAppPath());
+    if (bf::exists(package_directory / kTizenManifestLocation) &&
+        bf::exists(package_directory / kHybridConfigLocation))
+      return true;
+  } else {
+    bool tizen_manifest_found = false;
+    bool config_xml_found = false;
+    if (!ci::CheckPathInZipArchive(arg.c_str(), kTizenManifestLocation,
+                                   &tizen_manifest_found))
+      return false;
+    if (!ci::CheckPathInZipArchive(arg.c_str(), kHybridConfigLocation,
+                                   &config_xml_found))
+      return false;
+    if (tizen_manifest_found && config_xml_found)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace wgt
index 40a9a07..8c3776a 100644 (file)
@@ -26,6 +26,17 @@ class WgtAppQueryInterface : public common_installer::AppQueryInterface {
    * \return true if package is installed
    */
   bool IsAppInstalledByArgv(int argc, char** argv) override;
+
+  /**
+   * \brief This method is workaround for detecting installation of hybrid
+   *        application.
+   *
+   * \param argc main() argc argument passed to the backend
+   * \param argv main() argv argument passed to the backend
+   *
+   * \return true if package is hybrid
+   */
+  bool IsHybridApplication(int argc, char** argv);
 };
 
 }  // namespace wgt
index f2be1cd..6f117b3 100644 (file)
@@ -63,6 +63,8 @@ namespace wgt {
 
 WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
     : AppInstaller("wgt", pkgrmgr) {
+  context_->backend_data.set(new WgtBackendData());
+
   /* treat the request */
   switch (pkgmgr_->GetRequestType()) {
     case ci::RequestType::Install : {
diff --git a/src/wgt_backend/CMakeLists.txt b/src/wgt_backend/CMakeLists.txt
new file mode 100644 (file)
index 0000000..54f886e
--- /dev/null
@@ -0,0 +1,11 @@
+# Target - definition
+ADD_EXECUTABLE(${TARGET_WGT_BACKEND} "wgt_backend.cc")
+# Target - includes
+TARGET_INCLUDE_DIRECTORIES(${TARGET_WGT_BACKEND} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
+
+# Target - in-package deps
+TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PRIVATE ${TARGET_LIBNAME_WGT})
+TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PRIVATE ${TARGET_LIBNAME_HYBRID})
+
+# Install
+INSTALL(TARGETS ${TARGET_WGT_BACKEND} DESTINATION ${BINDIR})
similarity index 56%
rename from src/wgt/wgt_backend.cc
rename to src/wgt_backend/wgt_backend.cc
index 576e861..3d59c2e 100644 (file)
@@ -6,6 +6,7 @@
 #include <common/pkgmgr_interface.h>
 #include <cerrno>
 
+#include "hybrid/hybrid_installer.h"
 #include "wgt/wgt_app_query_interface.h"
 #include "wgt/wgt_installer.h"
 
@@ -18,6 +19,15 @@ int main(int argc, char** argv) {
     LOG(ERROR) << "Options of pkgmgr installer cannot be parsed";
     return EINVAL;
   }
-  wgt::WgtInstaller installer(pkgmgr);
-  return (installer.Run() == ci::AppInstaller::Result::OK) ? 0 : 1;
+
+  // This is workaround for hybrid apps as they requires much different flow
+  // but installer does not branch at all in current design
+  if (query_interface.IsHybridApplication(argc, argv)) {
+    LOG(INFO) << "Hybrid package detected";
+    hybrid::HybridInstaller installer(pkgmgr);
+    return (installer.Run() == ci::AppInstaller::Result::OK) ? 0 : 1;
+  } else {
+    wgt::WgtInstaller installer(pkgmgr);
+    return (installer.Run() == ci::AppInstaller::Result::OK) ? 0 : 1;
+  }
 }