From accca51d6a9e4e8384e3d131a2a459c7b86ad866 Mon Sep 17 00:00:00 2001 From: Lukasz Wysocki Date: Fri, 15 Jan 2016 11:11:29 +0100 Subject: [PATCH 01/16] Style and code fix Change-Id: I2579598545e3539944c78fcf0bc93f220eaf3512 --- src/wgt/step/step_wgt_backup_icons.cc | 3 ++- src/wgt/step/step_wgt_create_icons.cc | 5 +++-- src/wgt/step/step_wgt_recover_icons.cc | 2 +- src/wgt/step/step_wgt_recover_icons.h | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wgt/step/step_wgt_backup_icons.cc b/src/wgt/step/step_wgt_backup_icons.cc index c1d63e0..5544182 100644 --- a/src/wgt/step/step_wgt_backup_icons.cc +++ b/src/wgt/step/step_wgt_backup_icons.cc @@ -5,6 +5,7 @@ #include "wgt/step/step_wgt_backup_icons.h" #include +#include namespace { const char kSharedRes[] = "shared/res"; @@ -16,7 +17,7 @@ namespace wgt { namespace backup { common_installer::Step::Status StepWgtBackupIcons::process() { - // TODO (l.wysocki): As a temporary solution this will move icons into two + // TODO(l.wysocki): As a temporary solution this will move icons into two // destinations respectively {HOME}/.applications/icons, // and {APP_ROOT}/shared/res, when some project will stop using old // location ({HOME}/.applications/icons) then it can be removed from here. diff --git a/src/wgt/step/step_wgt_create_icons.cc b/src/wgt/step/step_wgt_create_icons.cc index 1bd73eb..c38f4c7 100644 --- a/src/wgt/step/step_wgt_create_icons.cc +++ b/src/wgt/step/step_wgt_create_icons.cc @@ -5,6 +5,7 @@ #include "wgt/step/step_wgt_create_icons.h" #include +#include #include "common/utils/glist_range.h" @@ -19,7 +20,7 @@ namespace wgt { namespace filesystem { common_installer::Step::Status StepWgtCreateIcons::process() { - // TODO (l.wysocki): As a temporary solution this will copy icons into two + // TODO(l.wysocki): As a temporary solution this will copy icons into two // destinations respectively {HOME}/.applications/icons, // and {APP_ROOT}/shared/res, when some project will stop using old // location ({HOME}/.applications/icons) then it can be removed from here. @@ -35,7 +36,7 @@ common_installer::Step::Status StepWgtCreateIcons::process() { icon_x* icon = reinterpret_cast(app->icon->data); bf::path icon_path = StepCreateIcons::GetIconRoot() / icon->text; if (icon->text) - free((void *)icon->text); + free(const_cast(icon->text)); icon->text = strdup(icon_path.c_str()); } } diff --git a/src/wgt/step/step_wgt_recover_icons.cc b/src/wgt/step/step_wgt_recover_icons.cc index 0149b78..995e609 100644 --- a/src/wgt/step/step_wgt_recover_icons.cc +++ b/src/wgt/step/step_wgt_recover_icons.cc @@ -16,7 +16,7 @@ namespace wgt { namespace filesystem { std::vector StepWgtRecoverIcons::GetIconsPaths() { - // TODO (l.wysocki): As a temporary solution this will move icons into two + // TODO(l.wysocki): As a temporary solution this will move icons into two // destinations respectively {HOME}/.applications/icons, // and {APP_ROOT}/shared/res, when some project will stop using old // location ({HOME}/.applications/icons) then it can be removed from here. diff --git a/src/wgt/step/step_wgt_recover_icons.h b/src/wgt/step/step_wgt_recover_icons.h index cf63981..5f88113 100644 --- a/src/wgt/step/step_wgt_recover_icons.h +++ b/src/wgt/step/step_wgt_recover_icons.h @@ -6,6 +6,7 @@ #define WGT_STEP_STEP_WGT_RECOVER_ICONS_H_ #include +#include namespace wgt { namespace filesystem { -- 2.7.4 From 782d65d706b0bc46e12a2e041a9331893c788f6c Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Mon, 18 Jan 2016 10:31:48 +0100 Subject: [PATCH 02/16] Fix icon copying 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: I8c5d3ba513bb47eed571c3363f657eacb429f82f --- src/hybrid/hybrid_installer.cc | 12 ++++--- src/wgt/CMakeLists.txt | 4 +-- src/wgt/step/step_generate_xml.cc | 23 ++------------ src/wgt/step/step_parse.cc | 15 ++++++++- src/wgt/step/step_wgt_backup_icons.cc | 31 ------------------ src/wgt/step/step_wgt_backup_icons.h | 36 --------------------- src/wgt/step/step_wgt_create_icons.cc | 56 --------------------------------- src/wgt/step/step_wgt_create_icons.h | 47 ---------------------------- src/wgt/step/step_wgt_patch_icons.cc | 57 ++++++++++++++++++++++++++++++++++ src/wgt/step/step_wgt_patch_icons.h | 37 ++++++++++++++++++++++ src/wgt/step/step_wgt_recover_icons.cc | 31 ------------------ src/wgt/step/step_wgt_recover_icons.h | 36 --------------------- src/wgt/wgt_app_query_interface.cc | 14 +++++++-- src/wgt/wgt_installer.cc | 26 +++++++++------- 14 files changed, 147 insertions(+), 278 deletions(-) delete mode 100644 src/wgt/step/step_wgt_backup_icons.cc delete mode 100644 src/wgt/step/step_wgt_backup_icons.h delete mode 100644 src/wgt/step/step_wgt_create_icons.cc delete mode 100644 src/wgt/step/step_wgt_create_icons.h create mode 100644 src/wgt/step/step_wgt_patch_icons.cc create mode 100644 src/wgt/step/step_wgt_patch_icons.h delete mode 100644 src/wgt/step/step_wgt_recover_icons.cc delete mode 100644 src/wgt/step/step_wgt_recover_icons.h diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index c8ec5ad..d044c7e 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -33,6 +33,7 @@ #include #include +#include #include "hybrid/hybrid_backend_data.h" #include "hybrid/step/step_encrypt_resources.h" @@ -44,7 +45,7 @@ #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_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" namespace ci = common_installer; @@ -70,8 +71,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); + AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -98,8 +100,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); + AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -148,8 +151,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); + AddStep(); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index 7f32240..b68e08b 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -11,10 +11,8 @@ SET(SRCS step/step_parse_recovery.cc step/step_rds_parse.cc step/step_rds_modify.cc - step/step_wgt_backup_icons.cc - step/step_wgt_create_icons.cc + step/step_wgt_patch_icons.cc step/step_wgt_patch_storage_directories.cc - step/step_wgt_recover_icons.cc step/step_wgt_resource_directory.cc step/step_add_default_privileges.cc wgt_app_query_interface.cc diff --git a/src/wgt/step/step_generate_xml.cc b/src/wgt/step/step_generate_xml.cc index 6be0750..b2090be 100644 --- a/src/wgt/step/step_generate_xml.cc +++ b/src/wgt/step/step_generate_xml.cc @@ -132,30 +132,13 @@ common_installer::Step::Status StepGenerateXml::GenerateApplicationCommonXml( xmlTextWriterEndElement(writer); } - // icon is renamed to if (app->icon) { icon_x* iconx = reinterpret_cast(app->icon->data); - bf::path app_icon = context_->pkg_path.get(); - // TODO(t.iwanek): type should not be used here - if (context_->pkg_type.get() == "wgt") { - app_icon /= "res/wgt"; - } else { - app_icon /= "shared/res"; - } - app_icon /= iconx->text; - bf::path icon = app->appid; - if (app_icon.has_extension()) - icon += app_icon.extension(); - else - icon += bf::path(".png"); - - if (bf::exists(app_icon)) { - xmlTextWriterWriteFormatElement(writer, BAD_CAST "icon", - "%s", BAD_CAST icon.c_str()); - } + xmlTextWriterWriteFormatElement( + writer, BAD_CAST "icon", "%s", BAD_CAST iconx->text); } else { // Default icon setting is role of the platform - LOG(DEBUG) << "Icon was not found in package"; + LOG(DEBUG) << "Icon was not found in application"; } for (image_x* image : GListRange(app->image)) { diff --git a/src/wgt/step/step_parse.cc b/src/wgt/step/step_parse.cc index 392196e..bab1d10 100644 --- a/src/wgt/step/step_parse.cc +++ b/src/wgt/step/step_parse.cc @@ -5,6 +5,8 @@ #include "wgt/step/step_parse.h" +#include + #include #include #include @@ -36,6 +38,8 @@ #include "wgt/wgt_backend_data.h" +namespace bf = boost::filesystem; + namespace { const std::string kManifestVersion = "1.0.0"; @@ -108,13 +112,22 @@ bool StepParse::FillInstallationInfo(manifest_x* manifest) { } bool StepParse::FillIconPaths(manifest_x* manifest) { + std::shared_ptr app_info = + std::static_pointer_cast( + parser_->GetManifestData(app_keys::kTizenApplicationKey)); + if (!app_info) { + LOG(ERROR) << "Application info manifest data has not been found."; + return false; + } std::shared_ptr icons_info = std::static_pointer_cast( parser_->GetManifestData(app_keys::kIconsKey)); if (icons_info.get()) { for (auto& application_icon : icons_info->icons()) { icon_x* icon = reinterpret_cast (calloc(1, sizeof(icon_x))); - icon->text = strdup(application_icon.path().c_str()); + bf::path icon_path = context_->root_application_path.get() + / app_info->package() / "res" / "wgt" / application_icon.path(); + icon->text = strdup(icon_path.c_str()); icon->lang = strdup(DEFAULT_LOCALE); manifest->icon = g_list_append(manifest->icon, icon); } diff --git a/src/wgt/step/step_wgt_backup_icons.cc b/src/wgt/step/step_wgt_backup_icons.cc deleted file mode 100644 index 5544182..0000000 --- a/src/wgt/step/step_wgt_backup_icons.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#include "wgt/step/step_wgt_backup_icons.h" - -#include -#include - -namespace { -const char kSharedRes[] = "shared/res"; - -namespace bf = boost::filesystem; -} // namespace - -namespace wgt { -namespace backup { - -common_installer::Step::Status StepWgtBackupIcons::process() { - // TODO(l.wysocki): As a temporary solution this will move icons into two - // destinations respectively {HOME}/.applications/icons, - // and {APP_ROOT}/shared/res, when some project will stop using old - // location ({HOME}/.applications/icons) then it can be removed from here. - std::vector paths { getIconPath(context_->uid.get()), - context_->root_application_path.get() - / context_->pkgid.get() / kSharedRes }; - return MoveIcons(paths); -} - -} // namespace backup -} // namespace wgt diff --git a/src/wgt/step/step_wgt_backup_icons.h b/src/wgt/step/step_wgt_backup_icons.h deleted file mode 100644 index dc62760..0000000 --- a/src/wgt/step/step_wgt_backup_icons.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#ifndef WGT_STEP_STEP_WGT_BACKUP_ICONS_H_ -#define WGT_STEP_STEP_WGT_BACKUP_ICONS_H_ - -#include -#include - -namespace wgt { -namespace backup { - -/** - *\brief Step responsible for creating backup for icons during update and - * uninstallation. - * Used by WGT backend - */ -class StepWgtBackupIcons : public common_installer::backup::StepBackupIcons { - public: - using StepBackupIcons::StepBackupIcons; - - /** - * \brief main logic of backuping icons - * - * \return Status::OK, if successful backup, Status::ERROR otherwise - */ - Status process() override; - - SCOPE_LOG_TAG(WgtBackupIcons) -}; - -} // namespace backup -} // namespace wgt - -#endif // WGT_STEP_STEP_WGT_BACKUP_ICONS_H_ diff --git a/src/wgt/step/step_wgt_create_icons.cc b/src/wgt/step/step_wgt_create_icons.cc deleted file mode 100644 index c38f4c7..0000000 --- a/src/wgt/step/step_wgt_create_icons.cc +++ /dev/null @@ -1,56 +0,0 @@ -// 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 "wgt/step/step_wgt_create_icons.h" - -#include -#include - -#include "common/utils/glist_range.h" - -namespace bf = boost::filesystem; -namespace ci = common_installer; - -namespace { -const char kResWgt[] = "res/wgt"; -} // namespace - -namespace wgt { -namespace filesystem { - -common_installer::Step::Status StepWgtCreateIcons::process() { - // TODO(l.wysocki): As a temporary solution this will copy icons into two - // destinations respectively {HOME}/.applications/icons, - // and {APP_ROOT}/shared/res, when some project will stop using old - // location ({HOME}/.applications/icons) then it can be removed from here. - std::vector paths { getIconPath(context_->uid.get()), - StepCreateIcons::GetIconRoot() }; - - // explicit step for wgt apps to add absolute path to icon in order to - // store it in db - ci::Step::Status result = CopyIcons(paths); - for (application_x* app : - GListRange(context_->manifest_data.get()->application)) { - if (app->icon) { - icon_x* icon = reinterpret_cast(app->icon->data); - bf::path icon_path = StepCreateIcons::GetIconRoot() / icon->text; - if (icon->text) - free(const_cast(icon->text)); - icon->text = strdup(icon_path.c_str()); - } - } - return result; -} - -boost::filesystem::path StepWgtCreateIcons::GetIconRoot() const { - return context_->pkg_path.get() / kResWgt; -} - -std::string StepWgtCreateIcons::GetAppTypeForIcons() const { - return "webapp"; -} - -} // namespace filesystem -} // namespace wgt - diff --git a/src/wgt/step/step_wgt_create_icons.h b/src/wgt/step/step_wgt_create_icons.h deleted file mode 100644 index a9501a3..0000000 --- a/src/wgt/step/step_wgt_create_icons.h +++ /dev/null @@ -1,47 +0,0 @@ -// 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 WGT_STEP_STEP_WGT_CREATE_ICONS_H_ -#define WGT_STEP_STEP_WGT_CREATE_ICONS_H_ - -#include - -#include - -#include - -namespace wgt { -namespace filesystem { - -/** - * \brief This step return path to widget icon - */ -class StepWgtCreateIcons - : public common_installer::filesystem::StepCreateIcons { - public: - using StepCreateIcons::StepCreateIcons; - - Status process() override; - - /** - * \brief Return path to widget icon - * - * \return path to widget icon - */ - boost::filesystem::path GetIconRoot() const override; - - /** - * \brief Return type of application for which icons should be created - * - * \return application type - */ - std::string GetAppTypeForIcons() const override; - - SCOPE_LOG_TAG(WgtCreateIcons) -}; - -} // namespace filesystem -} // namespace wgt - -#endif // WGT_STEP_STEP_WGT_CREATE_ICONS_H_ diff --git a/src/wgt/step/step_wgt_patch_icons.cc b/src/wgt/step/step_wgt_patch_icons.cc new file mode 100644 index 0000000..45da3de --- /dev/null +++ b/src/wgt/step/step_wgt_patch_icons.cc @@ -0,0 +1,57 @@ +// 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 "wgt/step/step_wgt_patch_icons.h" + +#include + +#include "common/utils/file_util.h" +#include "common/utils/glist_range.h" + +namespace bf = boost::filesystem; +namespace bs = boost::system; +namespace ci = common_installer; + +namespace { +const char kResWgt[] = "res/wgt"; +} // namespace + +namespace wgt { +namespace filesystem { + +common_installer::Step::Status StepWgtPatchIcons::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(context_->manifest_data.get()->application)) { + if (strcmp(app->type, "webapp") != 0) + continue; + if (app->icon) { + icon_x* icon = reinterpret_cast(app->icon->data); + bf::path icon_text(icon->text); + bf::path icon_path = common_icon_location / app->appid; + if (icon_text.has_extension()) + icon_path += icon_text.extension(); + else + icon_path += ".png"; + + bf::copy_file(icon->text, icon_path, + bf::copy_option::overwrite_if_exists, error); + if (error) { + LOG(ERROR) << "Failed to move icon from " << icon->text << " to " + << icon_path; + return Status::ICON_ERROR; + } + if (icon->text) + free(const_cast(icon->text)); + icon->text = strdup(icon_path.c_str()); + } + } + return Status::OK; +} + +} // namespace filesystem +} // namespace wgt + diff --git a/src/wgt/step/step_wgt_patch_icons.h b/src/wgt/step/step_wgt_patch_icons.h new file mode 100644 index 0000000..c5eabaa --- /dev/null +++ b/src/wgt/step/step_wgt_patch_icons.h @@ -0,0 +1,37 @@ +// 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 WGT_STEP_STEP_WGT_PATCH_ICONS_H_ +#define WGT_STEP_STEP_WGT_PATCH_ICONS_H_ + +#include + +#include + +#include + +namespace wgt { +namespace filesystem { + +/** + * @brief The StepWgtPatchIcons class + * Copy widget icons to standard location of icons - shared/res/ + * where StepCreateIcons excepts icons to be. + */ +class StepWgtPatchIcons : public common_installer::Step { + public: + using Step::Step; + + Status process() override; + Status undo() override { return Status::OK; } + Status clean() override { return Status::OK; } + Status precheck() override { return Status::OK; } + + SCOPE_LOG_TAG(WgtPatchIcons) +}; + +} // namespace filesystem +} // namespace wgt + +#endif // WGT_STEP_STEP_WGT_PATCH_ICONS_H_ diff --git a/src/wgt/step/step_wgt_recover_icons.cc b/src/wgt/step/step_wgt_recover_icons.cc deleted file mode 100644 index 995e609..0000000 --- a/src/wgt/step/step_wgt_recover_icons.cc +++ /dev/null @@ -1,31 +0,0 @@ -// 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 "wgt/step/step_wgt_recover_icons.h" - -#include - -namespace { -const char kSharedRes[] = "shared/res"; - -namespace bf = boost::filesystem; -} // namespace - -namespace wgt { -namespace filesystem { - -std::vector StepWgtRecoverIcons::GetIconsPaths() { - // TODO(l.wysocki): As a temporary solution this will move icons into two - // destinations respectively {HOME}/.applications/icons, - // and {APP_ROOT}/shared/res, when some project will stop using old - // location ({HOME}/.applications/icons) then it can be removed from here. - std::vector paths { bf::path(getIconPath(context_->uid.get())), - context_->root_application_path.get() - / context_->pkgid.get() / kSharedRes }; - return paths; -} - -} // namespace filesystem -} // namespace wgt - diff --git a/src/wgt/step/step_wgt_recover_icons.h b/src/wgt/step/step_wgt_recover_icons.h deleted file mode 100644 index 5f88113..0000000 --- a/src/wgt/step/step_wgt_recover_icons.h +++ /dev/null @@ -1,36 +0,0 @@ -// 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 WGT_STEP_STEP_WGT_RECOVER_ICONS_H_ -#define WGT_STEP_STEP_WGT_RECOVER_ICONS_H_ - -#include -#include - -namespace wgt { -namespace filesystem { - -/** - * @brief The StepRecoverIcons class - * Fixes state of platform icon files in recovery mode. - * - * For recovery of new installation, all icons files are removed. - * For recovery of update installation, all icons of applications of package are - * restored to its previous locations. - */ -class StepWgtRecoverIcons : - public common_installer::filesystem::StepRecoverIcons { - public: - using StepRecoverIcons::StepRecoverIcons; - - protected: - virtual std::vector GetIconsPaths(); - - SCOPE_LOG_TAG(WgtRecoverIcons) -}; - -} // namespace filesystem -} // namespace wgt - -#endif // WGT_STEP_STEP_WGT_RECOVER_ICONS_H_ diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 3f42f71..0dc580d 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -88,6 +89,13 @@ std::string GetPkgIdFromPath(const std::string& path) { return pkg_id; } +std::string ReadPkgidFromRecovery(const std::string& recovery_path) { + std::unique_ptr recovery_file = + ci::recovery::RecoveryFile::OpenRecoveryFileForPath(recovery_path); + recovery_file->Detach(); + return recovery_file->pkgid(); +} + } // namespace namespace wgt { @@ -104,10 +112,12 @@ bool WgtAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) { bool WgtAppQueryInterface::IsHybridApplication(int argc, char** argv) { std::string arg = GetInstallationRequestInfo(argc, argv); + if (arg.find("apps_rw/recovery-") != std::string::npos) + arg = ReadPkgidFromRecovery(arg); if (ci::IsPackageInstalled(arg, ci::GetRequestMode())) { bf::path package_directory(ci::GetRootAppPath()); - if (bf::exists(package_directory / kTizenManifestLocation) && - bf::exists(package_directory / kHybridConfigLocation)) + if (bf::exists(package_directory / arg / kTizenManifestLocation) && + bf::exists(package_directory / arg / kHybridConfigLocation)) return true; } else { bool tizen_manifest_found = false; diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 54e4bf0..c4d5ca9 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include #include #include @@ -22,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -51,10 +54,8 @@ #include "wgt/step/step_rds_modify.h" #include "wgt/step/step_rds_parse.h" #include "wgt/step/step_remove_encryption_data.h" -#include "wgt/step/step_wgt_backup_icons.h" -#include "wgt/step/step_wgt_create_icons.h" +#include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" -#include "wgt/step/step_wgt_recover_icons.h" #include "wgt/step/step_wgt_resource_directory.h" namespace ci = common_installer; @@ -82,7 +83,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -101,12 +103,13 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); - AddStep(); + AddStep(); + AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -151,12 +154,13 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); AddStep(); AddStep(); - AddStep(); AddStep(); - AddStep(); + AddStep(); + AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -168,7 +172,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 4288b8ecaa03b0cd14ad17182c2dc35b58887ea6 Mon Sep 17 00:00:00 2001 From: Lukasz Wysocki Date: Fri, 15 Jan 2016 12:50:16 +0100 Subject: [PATCH 03/16] Fix WGT handlers includes This change require following changes: - https://review.tizen.org/gerrit/#/c/57153/ Changes should be merged together Change-Id: I2bf7b13f47b57e5585addc10acbc686ae6752137 --- src/hybrid/hybrid_backend_data.h | 2 +- src/wgt/step/step_check_settings_level.cc | 2 +- src/wgt/step/step_check_wgt_background_category.cc | 2 +- src/wgt/step/step_parse.cc | 24 +++++++++++----------- src/wgt/step/step_parse.h | 4 ++-- src/wgt/wgt_app_query_interface.cc | 6 +++--- src/wgt/wgt_backend_data.h | 2 +- src/wgt/wgt_installer.cc | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/hybrid/hybrid_backend_data.h b/src/hybrid/hybrid_backend_data.h index c3a7d8b..7815a12 100644 --- a/src/hybrid/hybrid_backend_data.h +++ b/src/hybrid/hybrid_backend_data.h @@ -6,9 +6,9 @@ #define HYBRID_HYBRID_BACKEND_DATA_H_ #include -#include #include #include +#include #include #include diff --git a/src/wgt/step/step_check_settings_level.cc b/src/wgt/step/step_check_settings_level.cc index 0d88bb2..9df2b19 100644 --- a/src/wgt/step/step_check_settings_level.cc +++ b/src/wgt/step/step_check_settings_level.cc @@ -4,8 +4,8 @@ #include "wgt/step/step_check_settings_level.h" -#include #include +#include #include diff --git a/src/wgt/step/step_check_wgt_background_category.cc b/src/wgt/step/step_check_wgt_background_category.cc index c652fc2..087b37b 100644 --- a/src/wgt/step/step_check_wgt_background_category.cc +++ b/src/wgt/step/step_check_wgt_background_category.cc @@ -5,7 +5,7 @@ #include "wgt/step/step_check_wgt_background_category.h" #include -#include +#include #include "wgt/wgt_backend_data.h" diff --git a/src/wgt/step/step_parse.cc b/src/wgt/step/step_parse.cc index bab1d10..bed8524 100644 --- a/src/wgt/step/step_parse.cc +++ b/src/wgt/step/step_parse.cc @@ -11,18 +11,18 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/wgt/step/step_parse.h b/src/wgt/step/step_parse.h index e1f2547..0737b9d 100644 --- a/src/wgt/step/step_parse.h +++ b/src/wgt/step/step_parse.h @@ -11,9 +11,9 @@ #include #include -#include -#include #include +#include +#include #include #include diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 0dc580d..2798080 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -16,11 +16,11 @@ #include #include -#include -#include -#include #include #include +#include +#include +#include #include #include diff --git a/src/wgt/wgt_backend_data.h b/src/wgt/wgt_backend_data.h index e3c281b..15daa7e 100644 --- a/src/wgt/wgt_backend_data.h +++ b/src/wgt/wgt_backend_data.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index c4d5ca9..3db7e38 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -4,8 +4,6 @@ #include "wgt/wgt_installer.h" -#include - #include #include #include @@ -43,6 +41,8 @@ #include #include +#include + #include "wgt/step/step_add_default_privileges.h" #include "wgt/step/step_check_settings_level.h" #include "wgt/step/step_check_wgt_background_category.h" -- 2.7.4 From 3edf758ec62497cfacb2d615a155cec443cdd26e Mon Sep 17 00:00:00 2001 From: Lukasz Wysocki Date: Thu, 21 Jan 2016 13:15:37 +0100 Subject: [PATCH 04/16] Fix lib name for wgt-manifest-handlers Following commits should be merged together: - https://review.tizen.org/gerrit/#/c/57676/ - https://review.tizen.org/gerrit/#/c/57677/ - https://review.tizen.org/gerrit/#/c/57681/ Change-Id: I41d5e2adbbfd9606adeccd10ff703ff4a674412f --- CMakeLists.txt | 2 +- packaging/wgt-backend.spec | 2 +- src/wgt/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9a8224..10b8412 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ INCLUDE(ApplyPkgConfig) # Find all needed packages once PKG_CHECK_MODULES(APP_INSTALLERS_DEPS REQUIRED app-installers) -PKG_CHECK_MODULES(MANIFEST_HANDLERS_DEPS REQUIRED manifest-handlers) +PKG_CHECK_MODULES(WGT_MANIFEST_HANDLERS_DEPS REQUIRED wgt-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) diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec index fadbca2..ba0b65b 100644 --- a/packaging/wgt-backend.spec +++ b/packaging/wgt-backend.spec @@ -17,7 +17,7 @@ BuildRequires: cmake BuildRequires: gtest-devel BuildRequires: pkgconfig(app-installers) BuildRequires: pkgconfig(manifest-parser) -BuildRequires: pkgconfig(manifest-handlers) +BuildRequires: pkgconfig(wgt-manifest-handlers) BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(libwebappenc) BuildRequires: pkgconfig(tpk-installer) diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index b68e08b..6cb1e7a 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -33,7 +33,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_LIBNAME_WGT} PUBLIC "${CMAKE_CURRENT_SOURCE_ # Target - deps APPLY_PKG_CONFIG(${TARGET_LIBNAME_WGT} PUBLIC APP_INSTALLERS_DEPS - MANIFEST_HANDLERS_DEPS + WGT_MANIFEST_HANDLERS_DEPS MANIFEST_PARSER_DEPS PKGMGR_INSTALLER_DEPS ENCRYPTION_DEPS -- 2.7.4 From b7576ac13bb1e7bfc69a6bdf49106cd130c899b0 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Fri, 22 Jan 2016 10:38:45 +0100 Subject: [PATCH 05/16] Switch parsing procedures to StepParseManifest Run smoke tests to verify. Requires: - https://review.tizen.org/gerrit/57749 Change-Id: I1818cafd32f5347418f3f5b298b3cc4bcb62c2fc --- src/hybrid/hybrid_installer.cc | 30 ++++++++++++++++++++---------- src/wgt/wgt_installer.cc | 19 +++++++++++++------ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index d044c7e..d2070d5 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -16,8 +16,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -32,7 +31,6 @@ #include #include -#include #include #include "hybrid/hybrid_backend_data.h" @@ -60,7 +58,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) case ci::RequestType::Install: AddStep(pkgmgr_); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::PACKAGE, + ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); AddStep(true); AddStep(); @@ -85,7 +85,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) case ci::RequestType::Update: AddStep(pkgmgr_); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::PACKAGE, + ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); AddStep(true); AddStep(); @@ -95,7 +97,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); @@ -116,7 +120,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr 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(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); AddStep(); AddStep(); @@ -133,9 +139,11 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) case ci::RequestType::Delta: AddStep(pkgmgr_); AddStep(); - // TODO(t.iwanek): manifest is parsed twice... - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::PACKAGE, + ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); + // TODO(t.iwanek): manifest is parsed twice... AddStep(false); AddStep(); AddStep(); @@ -146,7 +154,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 3db7e38..ff190c6 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -100,7 +99,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); @@ -117,7 +118,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) } case ci::RequestType::Uninstall: { AddStep(pkgmgr_); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); AddStep(); AddStep(); @@ -132,7 +135,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep(false); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); @@ -151,7 +156,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::INSTALLED, + ci::parse::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 2a0ed3a6f3b584addf02fce8beba15bfeea0d5c5 Mon Sep 17 00:00:00 2001 From: Arkadiusz Szulakiewicz Date: Mon, 25 Jan 2016 16:18:49 +0100 Subject: [PATCH 06/16] Add default value for preload attribute Change-Id: Ia03197d404e4735797825a3a153f55766aa05712 --- src/wgt/step/step_parse.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wgt/step/step_parse.cc b/src/wgt/step/step_parse.cc index bed8524..705dc95 100644 --- a/src/wgt/step/step_parse.cc +++ b/src/wgt/step/step_parse.cc @@ -170,6 +170,7 @@ bool StepParse::FillWidgetInfo(manifest_x* manifest) { manifest->type = strdup("wgt"); manifest->appsetting = strdup("false"); manifest->nodisplay_setting = strdup("false"); + manifest->preload = strdup("false"); // For wgt package use the long name for (auto& item : wgt_info->name_set()) { @@ -523,6 +524,7 @@ common_installer::Step::Status StepParse::process() { const std::string& required_api_version = info->required_version(); manifest->api_version = strdup(required_api_version.c_str()); + context_->pkgid.set(manifest->package); // write pkgid for recovery file -- 2.7.4 From 7dfe7ddd172e04b433b9f0c28b71f9208512631a Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Fri, 15 Jan 2016 13:38:56 +0100 Subject: [PATCH 07/16] Fix recovery smoke test Requires: - https://review.tizen.org/gerrit/45316 Verify by: $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.RecoveryMode_ForInstallation $ /usr/bin/wgt-backend-ut/smoke_test --gtest_filter=SmokeTest.RecoveryMode_ForUpdate Change-Id: Iac901289fcbd17315a9d3ba4d73c1c06dbb3b18f --- src/unit_tests/smoke_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index ee47203..6cabbdf 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -63,6 +63,8 @@ class StepCrash : public ci::Step { void RemoveAllRecoveryFiles() { bf::path root_path = ci::GetRootAppPath(); + if (!bf::exists(root_path)) + return; for (auto& dir_entry : boost::make_iterator_range( bf::directory_iterator(root_path), bf::directory_iterator())) { if (bf::is_regular_file(dir_entry)) { @@ -275,7 +277,7 @@ ci::AppInstaller::Result DeltaInstall(const bf::path& path, ci::AppInstaller::Result Recover(const bf::path& recovery_file, RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-e", recovery_file.c_str()}; + const char* argv[] = {"", "-b", recovery_file.c_str()}; std::unique_ptr query_interface = CreateQueryInterface(); auto pkgmgr = -- 2.7.4 From 9560c5db25f94faa950f03028519720ec0e79685 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Mon, 18 Jan 2016 10:31:48 +0100 Subject: [PATCH 08/16] Recovery mode for hybrid application Requires: - https://review.tizen.org/gerrit/58104 Change-Id: I174cd185ad12bb97b406d250b3d339568e79345f --- src/hybrid/hybrid_installer.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index d2070d5..d26de1d 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -23,6 +23,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -42,6 +50,7 @@ #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_parse_recovery.h" #include "wgt/step/step_remove_encryption_data.h" #include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" @@ -173,8 +182,21 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); break; case ci::RequestType::Recovery: - // TODO(t.iwanek): implement recovery for hybrid apps if possible - AddStep(); + AddStep(pkgmgr_); + AddStep(); + AddStep( + ci::parse::StepParseManifest::ManifestLocation::RECOVERY, + ci::parse::StepParseManifest::StoreLocation::NORMAL); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); + AddStep(); break; default: AddStep(); -- 2.7.4 From 1d2f01661c428147f57d405f49b1a8d95e140d71 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Tue, 2 Feb 2016 16:48:25 +0100 Subject: [PATCH 09/16] Remove SmokeTest.DeinstallationMode_Rollback test According to force deinstallation requirement, there is no need for rollback of deinstallation. Deinstallation should never fail and remove as much of package installation as possible. Change-Id: Ia818e1174b2ff6518fb55a9320217403d31a94fa --- src/unit_tests/smoke_test.cc | 10 ---------- .../test_samples/smoke/DeinstallationMode_Rollback.wgt | Bin 33320 -> 0 bytes 2 files changed, 10 deletions(-) delete mode 100644 src/unit_tests/test_samples/smoke/DeinstallationMode_Rollback.wgt diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 6cabbdf..5373085 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -453,16 +453,6 @@ TEST_F(SmokeTest, UpdateMode_Rollback) { ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); } -TEST_F(SmokeTest, DeinstallationMode_Rollback) { - bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Rollback.wgt"; - std::string pkgid = "smokeapp08"; - std::string appid = "smokeapp08.DeinstallationModeRollback"; - ASSERT_EQ(Install(path), ci::AppInstaller::Result::OK); - ASSERT_EQ(Uninstall(pkgid, RequestResult::FAIL), - ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, appid); -} - } // namespace common_installer int main(int argc, char** argv) { diff --git a/src/unit_tests/test_samples/smoke/DeinstallationMode_Rollback.wgt b/src/unit_tests/test_samples/smoke/DeinstallationMode_Rollback.wgt deleted file mode 100644 index ea83495aa2e237f6c7e80a74acf3fc1d2ddf8292..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33320 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

egx4!dORJ>p=~%BDFL<-^~#hcLj4vi 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 Date: Tue, 2 Feb 2016 19:34:12 +0900 Subject: [PATCH 10/16] Check the given package is blacklisted when install Requires: - https://review.tizen.org/gerrit/#/c/58457/ Change-Id: I995b132ff5c3498187fba37cfbf4b088310d24ce Signed-off-by: Sangyoon Jang --- src/wgt/wgt_installer.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index ff190c6..a5eb03e 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep(); AddStep(true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -93,6 +95,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep(); AddStep(true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -138,6 +141,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep( ci::parse::StepParseManifest::ManifestLocation::INSTALLED, ci::parse::StepParseManifest::StoreLocation::BACKUP); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -150,6 +154,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(false); // start file may not have changed AddStep("res/wgt/"); AddStep(true); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 9c2a68ced9ff3a4ed7ad5923639a9e21654c15f4 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Thu, 28 Jan 2016 14:09:20 +0100 Subject: [PATCH 11/16] Implement PKGMGR_REQUEST_TYPE_CLEARDATA for wgt-backend Verify by running: pkgcmd -t wgt -c -n $pkgid_of_installed_package and check if all content of apps_rw/$pkgid/data/ was removed. Requires: - https://review.tizen.org/gerrit/58245 Change-Id: I56a3435bbda9f2034784a52e0f0ab81a1e1f9ca8 --- src/hybrid/hybrid_installer.cc | 5 +++++ src/wgt/wgt_installer.cc | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index d26de1d..e7ea48a 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,10 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); break; + case ci::RequestType::Clear: + AddStep(pkgmgr_); + AddStep(); + break; default: AddStep(); break; diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index a5eb03e..8cf97b0 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -191,6 +192,11 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); break; } + case ci::RequestType::Clear: { + AddStep(pkgmgr_); + AddStep(); + break; + } default: { AddStep(); } -- 2.7.4 From 56555d1509ea6e1ab49bdc33061c3a3913cd6336 Mon Sep 17 00:00:00 2001 From: Arkadiusz Szulakiewicz Date: Mon, 1 Feb 2016 16:01:43 +0100 Subject: [PATCH 12/16] Modify Uninstall procedure to allow force-uninstall Change-Id: Ib8336c4ecf53d96d3508d13e37776bd06487538d --- src/hybrid/hybrid_installer.cc | 3 ++- src/wgt/CMakeLists.txt | 1 + src/wgt/step/step_wgt_remove_manifest.cc | 40 ++++++++++++++++++++++++++++++++ src/wgt/step/step_wgt_remove_manifest.h | 40 ++++++++++++++++++++++++++++++++ src/wgt/wgt_installer.cc | 3 ++- 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/wgt/step/step_wgt_remove_manifest.cc create mode 100644 src/wgt/step/step_wgt_remove_manifest.h diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index e7ea48a..0a88baf 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -55,6 +55,7 @@ #include "wgt/step/step_remove_encryption_data.h" #include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" +#include "wgt/step/step_wgt_remove_manifest.h" namespace ci = common_installer; @@ -134,13 +135,13 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) ci::parse::StepParseManifest::ManifestLocation::INSTALLED, ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); break; case ci::RequestType::Reinstall: // RDS is not supported for hybrid apps diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index 6cb1e7a..405d9e4 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -14,6 +14,7 @@ SET(SRCS step/step_wgt_patch_icons.cc step/step_wgt_patch_storage_directories.cc step/step_wgt_resource_directory.cc + step/step_wgt_remove_manifest.cc step/step_add_default_privileges.cc wgt_app_query_interface.cc wgt_installer.cc diff --git a/src/wgt/step/step_wgt_remove_manifest.cc b/src/wgt/step/step_wgt_remove_manifest.cc new file mode 100644 index 0000000..68a982e --- /dev/null +++ b/src/wgt/step/step_wgt_remove_manifest.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#include "wgt/step/step_wgt_remove_manifest.h" + +#include +#include +#include + +#include +#include + +#include +#include + +#include "common/utils/file_util.h" + +namespace bf = boost::filesystem; +namespace bs = boost::system; + +namespace wgt { +namespace pkgmgr { + + +common_installer::Step::Status StepRemoveManifest::process() { + bs::error_code error; + bf::remove(context_->xml_path.get(), error); + + if (error) { + LOG(ERROR) << "Failed to remove xml manifest file"; + return Status::MANIFEST_ERROR; + } + LOG(DEBUG) << "Manifest file removed"; + return Status::OK; +} + + +} // namespace wgt +} // namespace pkgmgr diff --git a/src/wgt/step/step_wgt_remove_manifest.h b/src/wgt/step/step_wgt_remove_manifest.h new file mode 100644 index 0000000..459d633 --- /dev/null +++ b/src/wgt/step/step_wgt_remove_manifest.h @@ -0,0 +1,40 @@ +// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#ifndef WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ +#define WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ + +#include + +#include "common/installer_context.h" +#include "common/step/step.h" + +namespace wgt { +namespace pkgmgr { + +/** + * \brief Step responsbile for removing manifest file during uninstallation + */ +class StepRemoveManifest : public common_installer::Step { + public: + using common_installer::Step::Step; + + /** + * \brief main logic of remove manifest + * + * \return Status::OK if success, Status::ERROR otherwise + */ + Status process() override; + + Status clean() override { return Status::OK; } + Status undo() override { return Status::OK; } + Status precheck() override { return Status::OK; } + + SCOPE_LOG_TAG(RemoveManifest) +}; + +} // namespace pkgmgr +} // namespace wgt + +#endif // WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 8cf97b0..2397ebd 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -58,6 +58,7 @@ #include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" #include "wgt/step/step_wgt_resource_directory.h" +#include "wgt/step/step_wgt_remove_manifest.h" namespace ci = common_installer; @@ -126,13 +127,13 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::parse::StepParseManifest::ManifestLocation::INSTALLED, ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); break; } case ci::RequestType::Reinstall: { -- 2.7.4 From d99ec453082128f3660a689f12256511dfd10aed Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Thu, 4 Feb 2016 16:59:03 +0900 Subject: [PATCH 13/16] modify codes related to getting app_path. Requires: https://review.tizen.org/gerrit/#/c/58863 Change-Id: I1b971a87a8aa534a4a6526d9c3b6a70046a986d0 Signed-off-by: jongmyeongko --- src/unit_tests/smoke_test.cc | 14 +++++++------- src/wgt/wgt_app_query_interface.cc | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 5373085..f23d98b 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -62,7 +62,7 @@ class StepCrash : public ci::Step { }; void RemoveAllRecoveryFiles() { - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); if (!bf::exists(root_path)) return; for (auto& dir_entry : boost::make_iterator_range( @@ -77,7 +77,7 @@ void RemoveAllRecoveryFiles() { } bf::path FindRecoveryFile() { - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); for (auto& dir_entry : boost::make_iterator_range( bf::directory_iterator(root_path), bf::directory_iterator())) { if (bf::is_regular_file(dir_entry)) { @@ -92,7 +92,7 @@ bf::path FindRecoveryFile() { bool ValidateFileContentInPackage(const std::string& pkgid, const std::string& relative, const std::string& expected) { - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); bf::path file_path = root_path / pkgid / relative; if (!bf::exists(file_path)) { LOG(ERROR) << file_path << " doesn't exist"; @@ -113,7 +113,7 @@ bool ValidateFileContentInPackage(const std::string& pkgid, } void ValidatePackageFS(const std::string& pkgid, const std::string& appid) { - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); bf::path package_path = root_path / pkgid; bf::path binary_path = package_path / "bin" / appid; bf::path data_path = package_path / "data"; @@ -150,7 +150,7 @@ void ValidatePackageFS(const std::string& pkgid, const std::string& appid) { } void PackageCheckCleanup(const std::string& pkgid, const std::string& appid) { - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); bf::path package_path = root_path / pkgid; ASSERT_FALSE(bf::exists(package_path)); @@ -367,7 +367,7 @@ TEST_F(SmokeTest, RDSMode) { ValidatePackage(pkgid, appid); // Check delta modifications - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED")); ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED")); ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"); @@ -383,7 +383,7 @@ TEST_F(SmokeTest, DeltaMode) { ValidatePackage(pkgid, appid); // Check delta modifications - bf::path root_path = ci::GetRootAppPath(); + bf::path root_path = ci::GetRootAppPath(false); ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED")); ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED")); ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css")); // NOLINT diff --git a/src/wgt/wgt_app_query_interface.cc b/src/wgt/wgt_app_query_interface.cc index 2798080..b45389c 100644 --- a/src/wgt/wgt_app_query_interface.cc +++ b/src/wgt/wgt_app_query_interface.cc @@ -115,7 +115,7 @@ bool WgtAppQueryInterface::IsHybridApplication(int argc, char** argv) { if (arg.find("apps_rw/recovery-") != std::string::npos) arg = ReadPkgidFromRecovery(arg); if (ci::IsPackageInstalled(arg, ci::GetRequestMode())) { - bf::path package_directory(ci::GetRootAppPath()); + bf::path package_directory(ci::GetRootAppPath(false)); if (bf::exists(package_directory / arg / kTizenManifestLocation) && bf::exists(package_directory / arg / kHybridConfigLocation)) return true; -- 2.7.4 From 7a872dc25e2e82c90a43ed104152ec9ef607181b Mon Sep 17 00:00:00 2001 From: Arkadiusz Szulakiewicz Date: Thu, 4 Feb 2016 17:39:14 +0100 Subject: [PATCH 14/16] Minor improvements for force-uninstall step Change-Id: Ide952d967df1978cff123b14c2375557155031b9 --- src/wgt/step/step_remove_encryption_data.cc | 2 +- src/wgt/step/step_remove_encryption_data.h | 24 +++--------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/wgt/step/step_remove_encryption_data.cc b/src/wgt/step/step_remove_encryption_data.cc index 452f32b..0c601d3 100644 --- a/src/wgt/step/step_remove_encryption_data.cc +++ b/src/wgt/step/step_remove_encryption_data.cc @@ -11,7 +11,7 @@ namespace wgt { namespace encrypt { -common_installer::Step::Status StepRemoveEncryptionData::clean() { +common_installer::Step::Status StepRemoveEncryptionData::process() { wae_app_type_e enc_type = context_->request_mode.get() == common_installer::RequestMode::GLOBAL ? WAE_DOWNLOADED_GLOBAL_APP : WAE_DOWNLOADED_NORMAL_APP; diff --git a/src/wgt/step/step_remove_encryption_data.h b/src/wgt/step/step_remove_encryption_data.h index 291b92e..6156e99 100644 --- a/src/wgt/step/step_remove_encryption_data.h +++ b/src/wgt/step/step_remove_encryption_data.h @@ -22,36 +22,18 @@ class StepRemoveEncryptionData : public common_installer::Step { using Step::Step; /** - * \brief Empty method - the actual work is done in clean() to delay it - * - * \return Status::OK - */ - Status process() override { return Status::OK; } - - /** * \brief Remove encryption keys from database * - * \return Status::ERROR in case of failure, - * Status::OK otherwise - */ - Status clean() override; - - /** - * \brief Empty method - * * \return Status::OK */ + Status process() override; + Status clean() override { return Status::OK; } Status undo() override { return Status::OK; } - - /** - * \brief Empty method - * - * \return Status::OK - */ Status precheck() override { return Status::OK; } SCOPE_LOG_TAG(RemoveEncryptionData) }; } // namespace encrypt } // namespace wgt + #endif // WGT_STEP_STEP_REMOVE_ENCRYPTION_DATA_H_ -- 2.7.4 From 0d640c227d2a57b0f0b1c1519305ebca669ba977 Mon Sep 17 00:00:00 2001 From: Arkadiusz Szulakiewicz Date: Mon, 8 Feb 2016 15:52:31 +0100 Subject: [PATCH 15/16] Move step remove manifest to app-installer Requires: https://review.tizen.org/gerrit/59034 https://review.tizen.org/gerrit/59035 Change-Id: I0ecb72b1b9ea005c7beef34e35cfcef4fb884b04 --- src/hybrid/hybrid_installer.cc | 4 ++-- src/wgt/CMakeLists.txt | 1 - src/wgt/step/step_wgt_remove_manifest.cc | 40 -------------------------------- src/wgt/step/step_wgt_remove_manifest.h | 40 -------------------------------- src/wgt/wgt_installer.cc | 5 ++-- 5 files changed, 4 insertions(+), 86 deletions(-) delete mode 100644 src/wgt/step/step_wgt_remove_manifest.cc delete mode 100644 src/wgt/step/step_wgt_remove_manifest.h diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 0a88baf..48e693d 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -55,7 +56,6 @@ #include "wgt/step/step_remove_encryption_data.h" #include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" -#include "wgt/step/step_wgt_remove_manifest.h" namespace ci = common_installer; @@ -141,7 +141,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); break; case ci::RequestType::Reinstall: // RDS is not supported for hybrid apps diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index 405d9e4..6cb1e7a 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -14,7 +14,6 @@ SET(SRCS step/step_wgt_patch_icons.cc step/step_wgt_patch_storage_directories.cc step/step_wgt_resource_directory.cc - step/step_wgt_remove_manifest.cc step/step_add_default_privileges.cc wgt_app_query_interface.cc wgt_installer.cc diff --git a/src/wgt/step/step_wgt_remove_manifest.cc b/src/wgt/step/step_wgt_remove_manifest.cc deleted file mode 100644 index 68a982e..0000000 --- a/src/wgt/step/step_wgt_remove_manifest.cc +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#include "wgt/step/step_wgt_remove_manifest.h" - -#include -#include -#include - -#include -#include - -#include -#include - -#include "common/utils/file_util.h" - -namespace bf = boost::filesystem; -namespace bs = boost::system; - -namespace wgt { -namespace pkgmgr { - - -common_installer::Step::Status StepRemoveManifest::process() { - bs::error_code error; - bf::remove(context_->xml_path.get(), error); - - if (error) { - LOG(ERROR) << "Failed to remove xml manifest file"; - return Status::MANIFEST_ERROR; - } - LOG(DEBUG) << "Manifest file removed"; - return Status::OK; -} - - -} // namespace wgt -} // namespace pkgmgr diff --git a/src/wgt/step/step_wgt_remove_manifest.h b/src/wgt/step/step_wgt_remove_manifest.h deleted file mode 100644 index 459d633..0000000 --- a/src/wgt/step/step_wgt_remove_manifest.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#ifndef WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ -#define WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ - -#include - -#include "common/installer_context.h" -#include "common/step/step.h" - -namespace wgt { -namespace pkgmgr { - -/** - * \brief Step responsbile for removing manifest file during uninstallation - */ -class StepRemoveManifest : public common_installer::Step { - public: - using common_installer::Step::Step; - - /** - * \brief main logic of remove manifest - * - * \return Status::OK if success, Status::ERROR otherwise - */ - Status process() override; - - Status clean() override { return Status::OK; } - Status undo() override { return Status::OK; } - Status precheck() override { return Status::OK; } - - SCOPE_LOG_TAG(RemoveManifest) -}; - -} // namespace pkgmgr -} // namespace wgt - -#endif // WGT_STEP_STEP_WGT_REMOVE_MANIFEST_H_ diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 2397ebd..4eec68c 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -41,9 +41,9 @@ #include #include #include +#include #include - #include "wgt/step/step_add_default_privileges.h" #include "wgt/step/step_check_settings_level.h" #include "wgt/step/step_check_wgt_background_category.h" @@ -58,7 +58,6 @@ #include "wgt/step/step_wgt_patch_icons.h" #include "wgt/step/step_wgt_patch_storage_directories.h" #include "wgt/step/step_wgt_resource_directory.h" -#include "wgt/step/step_wgt_remove_manifest.h" namespace ci = common_installer; @@ -133,7 +132,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep(); + AddStep(); break; } case ci::RequestType::Reinstall: { -- 2.7.4 From ba3c463b3178e37dd367e5d5b950377548b402ad Mon Sep 17 00:00:00 2001 From: Lukasz Wartalowicz Date: Wed, 20 Jan 2016 14:22:56 +0100 Subject: [PATCH 16/16] Add StepRunParserPlugin to wgt-backend Requires: - https://review.tizen.org/gerrit/#/c/57334/ Add StepRunParserPlugin to wgt-backend Change-Id: I82179c534894f11de8e812e5d4c9fb9f4e8abfc1 --- src/hybrid/hybrid_installer.cc | 9 +++++++++ src/wgt/wgt_installer.cc | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 48e693d..12368b7 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Install); AddStep(); AddStep(); break; @@ -125,6 +128,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Upgrade); break; case ci::RequestType::Uninstall: AddStep(pkgmgr_); @@ -134,6 +139,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( ci::parse::StepParseManifest::ManifestLocation::INSTALLED, ci::parse::StepParseManifest::StoreLocation::NORMAL); + AddStep( + ci::PluginsLauncher::ActionType::Uninstall); AddStep(); AddStep(); AddStep(); @@ -182,6 +189,8 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Upgrade); break; case ci::RequestType::Recovery: AddStep(pkgmgr_); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 4eec68c..d3ca732 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Install); AddStep(); break; } @@ -117,6 +120,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Upgrade); AddStep(); break; } @@ -126,6 +131,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::parse::StepParseManifest::ManifestLocation::INSTALLED, ci::parse::StepParseManifest::StoreLocation::NORMAL); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Uninstall); AddStep(); AddStep(); AddStep(); @@ -176,6 +183,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep( + ci::PluginsLauncher::ActionType::Upgrade); AddStep(); break; } -- 2.7.4