From 3d4f35d407b05cb1bf750d00715efd00e2ec6d06 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Mon, 14 Dec 2015 16:19:55 +0100 Subject: [PATCH] Remove tpk and wgt backend code Source code is being transfered to separate git repositories. This repository will export devel package for those backends. Requires to be submitted together with commits moving source code of backends to repositories: - platform/appfw/wgt-backend, - platform/appfw/tpk-backend. Submit with: - https://review.tizen.org/gerrit/#/c/54291/, - https://review.tizen.org/gerrit/#/c/54886/. Change-Id: I7a4ba6f6dd732418ae896130010d22c99ceb8e30 --- CMakeLists.txt | 11 +- packaging/app-installers.spec | 44 +- packaging/tpk-backend.manifest | 8 - packaging/wgt-backend.manifest | 8 - src/CMakeLists.txt | 2 - src/common/CMakeLists.txt | 3 +- src/common/app-installers.pc.in | 2 +- src/tpk/CMakeLists.txt | 25 - src/tpk/step/step_check_tpk_background_category.cc | 24 - src/tpk/step/step_check_tpk_background_category.h | 32 - src/tpk/step/step_convert_xml.cc | 127 ---- src/tpk/step/step_convert_xml.h | 37 -- src/tpk/step/step_create_symbolic_link.cc | 94 --- src/tpk/step/step_create_symbolic_link.h | 26 - src/tpk/step/step_parse.cc | 671 --------------------- src/tpk/step/step_parse.h | 81 --- src/tpk/step/step_parse_recovery.cc | 55 -- src/tpk/step/step_parse_recovery.h | 32 - src/tpk/tpk_app_query_interface.cc | 119 ---- src/tpk/tpk_app_query_interface.h | 19 - src/tpk/tpk_backend.cc | 26 - src/tpk/tpk_installer.cc | 218 ------- src/tpk/tpk_installer.h | 42 -- src/unit_tests/CMakeLists.txt | 18 +- src/unit_tests/run-unit-tests.sh | 11 - src/unit_tests/smoke_test.cc | 587 ------------------ .../test_samples/smoke/DeinstallationMode.wgt | Bin 33312 -> 0 bytes .../smoke/DeinstallationMode_Rollback.wgt | Bin 33320 -> 0 bytes .../test_samples/smoke/DeinstallationMode_Tpk.tpk | Bin 27887 -> 0 bytes src/unit_tests/test_samples/smoke/DeltaMode.delta | Bin 1070 -> 0 bytes src/unit_tests/test_samples/smoke/DeltaMode.wgt | Bin 34283 -> 0 bytes .../test_samples/smoke/DeltaMode_Tpk.delta | Bin 1080 -> 0 bytes .../test_samples/smoke/DeltaMode_Tpk.tpk | Bin 28181 -> 0 bytes .../test_samples/smoke/InstallationMode.wgt | Bin 33311 -> 0 bytes .../smoke/InstallationMode_GoodSignature.wgt | Bin 38029 -> 0 bytes .../smoke/InstallationMode_Rollback.wgt | Bin 33320 -> 0 bytes .../test_samples/smoke/InstallationMode_Tpk.tpk | Bin 27885 -> 0 bytes .../smoke/InstallationMode_WrongSignature.wgt | Bin 37906 -> 0 bytes src/unit_tests/test_samples/smoke/RDSMode.wgt | Bin 34275 -> 0 bytes .../smoke/RecoveryMode_ForInstallation.wgt | Bin 33322 -> 0 bytes .../test_samples/smoke/RecoveryMode_ForUpdate.wgt | Bin 34140 -> 0 bytes .../smoke/RecoveryMode_ForUpdate_2.wgt | Bin 34140 -> 0 bytes .../smoke/RecoveryMode_Tpk_Installation.tpk | Bin 27892 -> 0 bytes .../test_samples/smoke/RecoveryMode_Tpk_Update.tpk | Bin 28032 -> 0 bytes .../smoke/RecoveryMode_Tpk_Update_2.tpk | Bin 28032 -> 0 bytes src/unit_tests/test_samples/smoke/UpdateMode.wgt | Bin 34134 -> 0 bytes src/unit_tests/test_samples/smoke/UpdateMode_2.wgt | Bin 34134 -> 0 bytes .../test_samples/smoke/UpdateMode_Rollback.wgt | Bin 34141 -> 0 bytes .../test_samples/smoke/UpdateMode_Rollback_2.wgt | Bin 34141 -> 0 bytes .../test_samples/smoke/UpdateMode_Tpk.tpk | Bin 28025 -> 0 bytes .../test_samples/smoke/UpdateMode_Tpk_2.tpk | Bin 28025 -> 0 bytes .../test_samples/smoke/delta_dir/.rds_delta | 6 - src/unit_tests/test_samples/smoke/delta_dir/ADDED | 0 .../test_samples/smoke/delta_dir/MODIFIED | 1 - .../test_samples/smoke/delta_dir/config.xml | 9 - src/wgt/CMakeLists.txt | 50 -- src/wgt/rds_parser.cc | 61 -- src/wgt/rds_parser.h | 63 -- src/wgt/step/step_add_default_privileges.cc | 38 -- src/wgt/step/step_add_default_privileges.h | 59 -- src/wgt/step/step_check_settings_level.cc | 47 -- src/wgt/step/step_check_settings_level.h | 59 -- src/wgt/step/step_check_wgt_background_category.cc | 29 - src/wgt/step/step_check_wgt_background_category.h | 32 - src/wgt/step/step_create_symbolic_link.cc | 71 --- src/wgt/step/step_create_symbolic_link.h | 61 -- src/wgt/step/step_encrypt_resources.cc | 214 ------- src/wgt/step/step_encrypt_resources.h | 66 -- src/wgt/step/step_generate_xml.cc | 492 --------------- src/wgt/step/step_generate_xml.h | 45 -- src/wgt/step/step_parse.cc | 574 ------------------ src/wgt/step/step_parse.h | 100 --- src/wgt/step/step_parse_recovery.cc | 56 -- src/wgt/step/step_parse_recovery.h | 63 -- src/wgt/step/step_rds_modify.cc | 226 ------- src/wgt/step/step_rds_modify.h | 87 --- src/wgt/step/step_rds_parse.cc | 50 -- src/wgt/step/step_rds_parse.h | 61 -- src/wgt/step/step_remove_encryption_data.cc | 54 -- src/wgt/step/step_remove_encryption_data.h | 57 -- src/wgt/step/step_wgt_copy_storage_directories.cc | 172 ------ src/wgt/step/step_wgt_copy_storage_directories.h | 58 -- src/wgt/step/step_wgt_create_icons.cc | 22 - src/wgt/step/step_wgt_create_icons.h | 36 -- .../step/step_wgt_create_storage_directories.cc | 102 ---- src/wgt/step/step_wgt_create_storage_directories.h | 77 --- src/wgt/step/step_wgt_resource_directory.cc | 44 -- src/wgt/step/step_wgt_resource_directory.h | 62 -- src/wgt/wgt_app_query_interface.cc | 100 --- src/wgt/wgt_app_query_interface.h | 33 - src/wgt/wgt_backend.cc | 23 - src/wgt/wgt_backend_data.h | 47 -- src/wgt/wgt_installer.cc | 179 ------ src/wgt/wgt_installer.h | 31 - 94 files changed, 10 insertions(+), 6029 deletions(-) delete mode 100644 packaging/tpk-backend.manifest delete mode 100644 packaging/wgt-backend.manifest delete mode 100644 src/tpk/CMakeLists.txt delete mode 100644 src/tpk/step/step_check_tpk_background_category.cc delete mode 100644 src/tpk/step/step_check_tpk_background_category.h delete mode 100644 src/tpk/step/step_convert_xml.cc delete mode 100644 src/tpk/step/step_convert_xml.h delete mode 100644 src/tpk/step/step_create_symbolic_link.cc delete mode 100644 src/tpk/step/step_create_symbolic_link.h delete mode 100644 src/tpk/step/step_parse.cc delete mode 100644 src/tpk/step/step_parse.h delete mode 100644 src/tpk/step/step_parse_recovery.cc delete mode 100644 src/tpk/step/step_parse_recovery.h delete mode 100644 src/tpk/tpk_app_query_interface.cc delete mode 100644 src/tpk/tpk_app_query_interface.h delete mode 100644 src/tpk/tpk_backend.cc delete mode 100644 src/tpk/tpk_installer.cc delete mode 100644 src/tpk/tpk_installer.h delete mode 100755 src/unit_tests/run-unit-tests.sh delete mode 100644 src/unit_tests/smoke_test.cc delete mode 100644 src/unit_tests/test_samples/smoke/DeinstallationMode.wgt delete mode 100644 src/unit_tests/test_samples/smoke/DeinstallationMode_Rollback.wgt delete mode 100644 src/unit_tests/test_samples/smoke/DeinstallationMode_Tpk.tpk delete mode 100644 src/unit_tests/test_samples/smoke/DeltaMode.delta delete mode 100644 src/unit_tests/test_samples/smoke/DeltaMode.wgt delete mode 100644 src/unit_tests/test_samples/smoke/DeltaMode_Tpk.delta delete mode 100644 src/unit_tests/test_samples/smoke/DeltaMode_Tpk.tpk delete mode 100644 src/unit_tests/test_samples/smoke/InstallationMode.wgt delete mode 100644 src/unit_tests/test_samples/smoke/InstallationMode_GoodSignature.wgt delete mode 100644 src/unit_tests/test_samples/smoke/InstallationMode_Rollback.wgt delete mode 100644 src/unit_tests/test_samples/smoke/InstallationMode_Tpk.tpk delete mode 100644 src/unit_tests/test_samples/smoke/InstallationMode_WrongSignature.wgt delete mode 100644 src/unit_tests/test_samples/smoke/RDSMode.wgt delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_ForInstallation.wgt delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_ForUpdate.wgt delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_ForUpdate_2.wgt delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_Tpk_Installation.tpk delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_Tpk_Update.tpk delete mode 100644 src/unit_tests/test_samples/smoke/RecoveryMode_Tpk_Update_2.tpk delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode.wgt delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode_2.wgt delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode_Rollback.wgt delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode_Rollback_2.wgt delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode_Tpk.tpk delete mode 100644 src/unit_tests/test_samples/smoke/UpdateMode_Tpk_2.tpk delete mode 100644 src/unit_tests/test_samples/smoke/delta_dir/.rds_delta delete mode 100644 src/unit_tests/test_samples/smoke/delta_dir/ADDED delete mode 100644 src/unit_tests/test_samples/smoke/delta_dir/MODIFIED delete mode 100644 src/unit_tests/test_samples/smoke/delta_dir/config.xml delete mode 100644 src/wgt/CMakeLists.txt delete mode 100644 src/wgt/rds_parser.cc delete mode 100644 src/wgt/rds_parser.h delete mode 100644 src/wgt/step/step_add_default_privileges.cc delete mode 100644 src/wgt/step/step_add_default_privileges.h delete mode 100644 src/wgt/step/step_check_settings_level.cc delete mode 100644 src/wgt/step/step_check_settings_level.h delete mode 100644 src/wgt/step/step_check_wgt_background_category.cc delete mode 100644 src/wgt/step/step_check_wgt_background_category.h delete mode 100644 src/wgt/step/step_create_symbolic_link.cc delete mode 100644 src/wgt/step/step_create_symbolic_link.h delete mode 100644 src/wgt/step/step_encrypt_resources.cc delete mode 100644 src/wgt/step/step_encrypt_resources.h delete mode 100644 src/wgt/step/step_generate_xml.cc delete mode 100644 src/wgt/step/step_generate_xml.h delete mode 100644 src/wgt/step/step_parse.cc delete mode 100644 src/wgt/step/step_parse.h delete mode 100644 src/wgt/step/step_parse_recovery.cc delete mode 100644 src/wgt/step/step_parse_recovery.h delete mode 100644 src/wgt/step/step_rds_modify.cc delete mode 100644 src/wgt/step/step_rds_modify.h delete mode 100644 src/wgt/step/step_rds_parse.cc delete mode 100644 src/wgt/step/step_rds_parse.h delete mode 100644 src/wgt/step/step_remove_encryption_data.cc delete mode 100644 src/wgt/step/step_remove_encryption_data.h delete mode 100644 src/wgt/step/step_wgt_copy_storage_directories.cc delete mode 100644 src/wgt/step/step_wgt_copy_storage_directories.h delete mode 100644 src/wgt/step/step_wgt_create_icons.cc delete mode 100644 src/wgt/step/step_wgt_create_icons.h delete mode 100644 src/wgt/step/step_wgt_create_storage_directories.cc delete mode 100644 src/wgt/step/step_wgt_create_storage_directories.h delete mode 100644 src/wgt/step/step_wgt_resource_directory.cc delete mode 100644 src/wgt/step/step_wgt_resource_directory.h delete mode 100644 src/wgt/wgt_app_query_interface.cc delete mode 100644 src/wgt/wgt_app_query_interface.h delete mode 100644 src/wgt/wgt_backend.cc delete mode 100644 src/wgt/wgt_backend_data.h delete mode 100644 src/wgt/wgt_installer.cc delete mode 100644 src/wgt/wgt_installer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e0e9f61..72edc95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,10 +23,6 @@ SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++11 -g --coverage") # Targets SET(TARGET_LIBNAME_COMMON "app-installers") -SET(TARGET_LIBNAME_WGT "wgt-installer") -SET(TARGET_LIBNAME_TPK "tpk-installer") -SET(TARGET_WGT_BACKEND "wgt-backend") -SET(TARGET_TPK_BACKEND "tpk-backend") SET(TARGET_PKGDIR_TOOL "pkgdir-tool") ADD_DEFINITIONS("-Wall") @@ -45,16 +41,13 @@ PKG_CHECK_MODULES(MINIZIP_DEPS REQUIRED minizip) PKG_CHECK_MODULES(ZLIB_DEPS REQUIRED zlib) PKG_CHECK_MODULES(TZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config) PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager) -PKG_CHECK_MODULES(MANIFEST_PARSER_DEPS REQUIRED manifest-parser) -PKG_CHECK_MODULES(MANIFEST_HANDLERS_DEPS REQUIRED manifest-handlers) PKG_CHECK_MODULES(DELTA_MANIFEST_HANDLERS_DEPS REQUIRED delta-manifest-handlers) -PKG_CHECK_MODULES(TPK_MANIFEST_HANDLERS_DEPS REQUIRED tpk-manifest-handlers) -PKG_CHECK_MODULES(CERT_SVC_DEPS_VCORE REQUIRED cert-svc-vcore) +PKG_CHECK_MODULES(MANIFEST_PARSER_UTILS_DEPS REQUIRED manifest-parser-utils) +PKG_CHECK_MODULES(CERT_SVC_DEPS_VCORE_DEPS REQUIRED cert-svc-vcore) PKG_CHECK_MODULES(PKGMGR_PARSER_DEPS REQUIRED pkgmgr-parser) PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info) PKG_CHECK_MODULES(LIBXML_DEPS REQUIRED libxml-2.0) PKG_CHECK_MODULES(PRIVILEGE_CHECKER_DEPS REQUIRED capi-security-privilege-manager) -PKG_CHECK_MODULES(ENCRYPTION_DEPS REQUIRED libwebappenc) PKG_CHECK_MODULES(APPMANAGER_DEPS REQUIRED capi-appfw-app-manager) FIND_PACKAGE(Boost REQUIRED COMPONENTS system filesystem regex program_options) diff --git a/packaging/app-installers.spec b/packaging/app-installers.spec index 19b6f81..0fc9088 100644 --- a/packaging/app-installers.spec +++ b/packaging/app-installers.spec @@ -9,9 +9,7 @@ Group: Application Framework/Package Management License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1000: app-installers.manifest -Source1001: wgt-backend.manifest -Source1002: tpk-backend.manifest -Source1003: app-installers-tests.manifest +Source1001: app-installers-tests.manifest BuildRequires: boost-devel BuildRequires: cmake @@ -29,34 +27,19 @@ BuildRequires: pkgconfig(minizip) BuildRequires: pkgconfig(libzip) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(cert-svc-vcore) -BuildRequires: pkgconfig(manifest-parser) -BuildRequires: pkgconfig(manifest-handlers) +BuildRequires: pkgconfig(manifest-parser-utils) BuildRequires: pkgconfig(delta-manifest-handlers) BuildRequires: pkgconfig(capi-security-privilege-manager) -BuildRequires: pkgconfig(libwebappenc) BuildRequires: pkgconfig(capi-appfw-app-manager) Requires: ca-certificates-tizen Requires: libtzplatform-config Requires: xdelta3 - %description This is a meta package that installs the common application installers of Tizen. -%package -n wgt-backend -Summary: Backend of WGT files - -%description -n wgt-backend -Backend for standard widget files WGT - -%package -n tpk-backend -Summary: Backend of TPK files - -%description -n tpk-backend -Backend for tizen package files - %package devel Summary: App-installers development files Group: Application Framework/Package Management @@ -77,25 +60,14 @@ Unit tests for al modules of app-installers cp %{SOURCE1000} . cp %{SOURCE1001} . -cp %{SOURCE1002} . -cp %{SOURCE1003} . %build -#Variable for setting symlink to runtime -runtime_path=%{_bindir}/xwalk-launcher -%if "%{profile}" == "mobile" || "%{profile}" == "wearable" || "%{profile}" == "tv" -runtime_path=%{_bindir}/wrt -%endif -%cmake . -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} -DWRT_LAUNCHER=${runtime_path} +%cmake . -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} make %{?_smp_mflags} %install %make_install -mkdir -p %{buildroot}/etc/package-manager/backend -ln -s %{_bindir}/wgt-backend %{buildroot}%{_sysconfdir}/package-manager/backend/wgt -ln -s %{_bindir}/tpk-backend %{buildroot}%{_sysconfdir}/package-manager/backend/tpk - %post ln -sf %{_bindir}/pkgdir-tool %{_bindir}/pkgdir_maker @@ -110,16 +82,6 @@ ln -sf %{_bindir}/pkgdir-tool %{_bindir}/pkgdir_maker %attr(6750,root,users) %{_bindir}/pkgdir-tool %license LICENSE -%files -n wgt-backend -%manifest wgt-backend.manifest -%{_sysconfdir}/package-manager/backend/wgt -%{_bindir}/wgt-backend - -%files -n tpk-backend -%{_sysconfdir}/package-manager/backend/tpk -%manifest tpk-backend.manifest -%{_bindir}/tpk-backend - %files devel %{_includedir}/app-installers/common/*.h %{_includedir}/app-installers/common/*/*.h diff --git a/packaging/tpk-backend.manifest b/packaging/tpk-backend.manifest deleted file mode 100644 index 925f49b..0000000 --- a/packaging/tpk-backend.manifest +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/packaging/wgt-backend.manifest b/packaging/wgt-backend.manifest deleted file mode 100644 index 55125da..0000000 --- a/packaging/wgt-backend.manifest +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8d7337..d1a2d79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,3 @@ ADD_SUBDIRECTORY(common) -ADD_SUBDIRECTORY(wgt) -ADD_SUBDIRECTORY(tpk) ADD_SUBDIRECTORY(pkgdir_tool) ADD_SUBDIRECTORY(unit_tests) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 4a15a29..94cac15 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -60,10 +60,11 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_COMMON} PUBLIC PKGMGR_INFO_DEPS PKGMGR_PARSER_DEPS PKGMGR_INSTALLER_DEPS + MANIFEST_PARSER_UTILS_DEPS SECURITY_MANAGER_DEPS TZPLATFORM_CONFIG_DEPS LIBXML_DEPS - CERT_SVC_DEPS_VCORE + CERT_SVC_DEPS_VCORE_DEPS MINIZIP_DEPS ZLIB_DEPS PRIVILEGE_CHECKER_DEPS diff --git a/src/common/app-installers.pc.in b/src/common/app-installers.pc.in index 0d1f585..2949579 100644 --- a/src/common/app-installers.pc.in +++ b/src/common/app-installers.pc.in @@ -6,6 +6,6 @@ includedir=@INCLUDEDIR@ Name: app-installers Description: Common library for pkgmgr backends Version: @VERSION@ -Requires: pkgmgr pkgmgr-installer minizip zlib libtzplatform-config security-manager manifest-parser manifest-handlers delta-manifest-handlers tpk-manifest-handlers cert-svc-vcore pkgmgr-parser pkgmgr-info libxml-2.0 capi-security-privilege-manager libwebappenc capi-appfw-app-manager +Requires: pkgmgr pkgmgr-installer minizip zlib libtzplatform-config security-manager manifest-parser-utils delta-manifest-handlers cert-svc-vcore pkgmgr-parser pkgmgr-info libxml-2.0 capi-security-privilege-manager capi-appfw-app-manager Libs: -L${libdir} -lapp-installers Cflags: -I${includedir}/app-installers/ diff --git a/src/tpk/CMakeLists.txt b/src/tpk/CMakeLists.txt deleted file mode 100644 index 7301962..0000000 --- a/src/tpk/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -SET(SRCS - step/step_check_tpk_background_category.cc - step/step_create_symbolic_link.cc - step/step_parse.cc - step/step_parse_recovery.cc - step/step_convert_xml.cc - tpk_app_query_interface.cc - tpk_installer.cc -) -ADD_LIBRARY(${TARGET_LIBNAME_TPK} STATIC ${SRCS}) -ADD_EXECUTABLE(${TARGET_TPK_BACKEND} "tpk_backend.cc") - -TARGET_INCLUDE_DIRECTORIES(${TARGET_LIBNAME_TPK} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../") -TARGET_INCLUDE_DIRECTORIES(${TARGET_TPK_BACKEND} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../") - -APPLY_PKG_CONFIG(${TARGET_LIBNAME_TPK} - PUBLIC PKGMGR_DEPS - TPK_MANIFEST_HANDLERS_DEPS - MANIFEST_PARSER_DEPS - Boost -) -TARGET_LINK_LIBRARIES(${TARGET_LIBNAME_TPK} PUBLIC ${TARGET_LIBNAME_COMMON}) -TARGET_LINK_LIBRARIES(${TARGET_TPK_BACKEND} PRIVATE ${TARGET_LIBNAME_TPK}) - -INSTALL(TARGETS ${TARGET_TPK_BACKEND} DESTINATION ${BINDIR}) diff --git a/src/tpk/step/step_check_tpk_background_category.cc b/src/tpk/step/step_check_tpk_background_category.cc deleted file mode 100644 index cd2a30c..0000000 --- a/src/tpk/step/step_check_tpk_background_category.cc +++ /dev/null @@ -1,24 +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 "common/installer_context.h" -#include "tpk/step/step_check_tpk_background_category.h" - -namespace { -namespace ci_sec = common_installer::security; -} // namespace - -namespace tpk { -namespace security { - -StepCheckTpkBackgroundCategory::StepCheckTpkBackgroundCategory( - common_installer::InstallerContext* context) : - ci_sec::StepCheckBackgroundCategory(context) {} - -bool StepCheckTpkBackgroundCategory::GetBackgroundSupport() { - return true; -} - -} // namespace security -} // namespace tpk diff --git a/src/tpk/step/step_check_tpk_background_category.h b/src/tpk/step/step_check_tpk_background_category.h deleted file mode 100644 index d6ce75a..0000000 --- a/src/tpk/step/step_check_tpk_background_category.h +++ /dev/null @@ -1,32 +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 TPK_STEP_STEP_CHECK_TPK_BACKGROUND_CATEGORY_H_ -#define TPK_STEP_STEP_CHECK_TPK_BACKGROUND_CATEGORY_H_ - -#include - -#include "common/step/step_check_background_category.h" - -namespace tpk { -namespace security { - -/** - * \brief This step check background category value and modify it depending on - * required version, cert level, background support, and value itself - */ -class StepCheckTpkBackgroundCategory : - public common_installer::security::StepCheckBackgroundCategory { - public: - explicit StepCheckTpkBackgroundCategory( - common_installer::InstallerContext* context); - - protected: - bool GetBackgroundSupport() override; -}; - -} // namespace security -} // namespace tpk - -#endif // TPK_STEP_STEP_CHECK_TPK_BACKGROUND_CATEGORY_H_ diff --git a/src/tpk/step/step_convert_xml.cc b/src/tpk/step/step_convert_xml.cc deleted file mode 100644 index 6051901..0000000 --- a/src/tpk/step/step_convert_xml.cc +++ /dev/null @@ -1,127 +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 "tpk/step/step_convert_xml.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "common/utils/glist_range.h" - -namespace bs = boost::system; -namespace bf = boost::filesystem; - -namespace { - -const xmlChar kExecAttributeKey[] = "exec"; -const xmlChar kXmlNamespaceUri[] = "http://tizen.org/ns/packages"; -const char kXmlXPathAppExpr[] = - "//*[local-name()='ui-application' or local-name()='service-application' " - "or local-name()='widget-application']"; - -} // namespace - -namespace common_installer { -namespace tpk { - -Step::Status StepConvertXml::precheck() { - bf::path xml_path = context_->pkg_path.get(); - xml_path /= "tizen-manifest.xml"; - - if (!bf::exists(xml_path)) { - LOG(ERROR) << "Cannot find manifest file"; - return Step::Status::INVALID_VALUE; - } - - xml_path_ = xml_path; - - return Step::Status::OK; -} - -bool StepConvertXml::ConvertXml(xmlDocPtr doc) { - xmlXPathContextPtr xpath_ctx; - - xpath_ctx = xmlXPathNewContext(doc); - if (!xpath_ctx) { - LOG(ERROR) << "Failed to create XPath context"; - return false; - } - - for (application_x* app : - GListRange(context_->manifest_data.get()->application)) { - std::string expr; - xmlXPathObjectPtr xpath_obj; - xmlNodePtr node; - - expr = std::string(kXmlXPathAppExpr) + "[@appid='" + app->appid + "']"; - xpath_obj = xmlXPathEvalExpression((const xmlChar*)expr.c_str(), xpath_ctx); - if (!xpath_obj || !xpath_obj->nodesetval || !xpath_obj->nodesetval->nodeNr) - continue; - - node = xpath_obj->nodesetval->nodeTab[0]; - xmlSetProp(node, kExecAttributeKey, (const xmlChar*)app->exec); - xmlXPathFreeObject(xpath_obj); - } - - xmlXPathFreeContext(xpath_ctx); - - return true; -} - -Step::Status StepConvertXml::process() { - xmlDocPtr doc = xmlParseFile(xml_path_.string().c_str()); - if (!doc) { - LOG(ERROR) << "Failed to parse xml file"; - return Step::Status::ERROR; - } - - if (!ConvertXml(doc)) - return Step::Status::ERROR; - - bf::path new_path = bf::path(getUserManifestPath(context_->uid.get())) - / bf::path(context_->pkgid.get()); - new_path += ".xml"; - if (xmlSaveFile(new_path.string().c_str(), doc) == -1) { - LOG(ERROR) << "Failed to write xml file"; - return Step::Status::ERROR; - } - - context_->xml_path.set(new_path.string()); - - if (pkgmgr_parser_check_manifest_validation( - context_->xml_path.get().c_str()) != 0) { - LOG(ERROR) << "Manifest is not valid"; - return Step::Status::ERROR; - } - - LOG(DEBUG) << "Successfully create manifest xml " - << context_->xml_path.get(); - - return Step::Status::OK; -} - -Step::Status StepConvertXml::clean() { - return Step::Status::OK; -} - -Step::Status StepConvertXml::undo() { - bs::error_code error; - - if (bf::exists(context_->xml_path.get())) - bf::remove_all(context_->xml_path.get(), error); - - return Step::Status::OK; -} - -} // namespace tpk -} // namespace common_installer diff --git a/src/tpk/step/step_convert_xml.h b/src/tpk/step/step_convert_xml.h deleted file mode 100644 index 9f129fb..0000000 --- a/src/tpk/step/step_convert_xml.h +++ /dev/null @@ -1,37 +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 TPK_STEP_STEP_CONVERT_XML_H_ -#define TPK_STEP_STEP_CONVERT_XML_H_ - -#include - -#include -#include - -#include "common/step/step.h" - -namespace common_installer { -namespace tpk { - -class StepConvertXml : public common_installer::Step { - public: - using Step::Step; - - Status process() override; - Status clean() override; - Status undo() override; - Status precheck() override; - - private: - boost::filesystem::path xml_path_; - bool ConvertXml(xmlDocPtr doc); - - SCOPE_LOG_TAG(ConvertXml) -}; - -} // namespace tpk -} // namespace common_installer - -#endif // TPK_STEP_STEP_CONVERT_XML_H_ diff --git a/src/tpk/step/step_create_symbolic_link.cc b/src/tpk/step/step_create_symbolic_link.cc deleted file mode 100644 index 8c1aab1..0000000 --- a/src/tpk/step/step_create_symbolic_link.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */ -#include "tpk/step/step_create_symbolic_link.h" -#include -#include -#include - -#include - -#include "common/step/step.h" -#include "common/app_installer.h" -#include "common/installer_context.h" -#include "common/utils/file_util.h" -#include "common/utils/glist_range.h" - -namespace tpk { -namespace filesystem { - -namespace bf = boost::filesystem; -using common_installer::InstallerContext; -typedef common_installer::Step::Status Status; - -namespace { - -bool CreateSymLink(application_x* app, InstallerContext* context) { - boost::system::error_code boost_error; - bf::path bindir = context->pkg_path.get() / - bf::path("bin"); - LOG(DEBUG) << "Creating dir: " << bindir; - if (!common_installer::CreateDir(bindir)) { - LOG(ERROR) << "Directory creation failure: " << bindir; - return false; - } - - // Exec path - // Make a symlink with the name of appid, pointing exec file - bf::path symlink_path = bindir / bf::path(app->appid); - LOG(DEBUG) << "Creating symlink " << symlink_path << " pointing " << - app->exec; - bf::create_symlink(bf::path(app->exec), symlink_path, boost_error); - if (boost_error) { - LOG(ERROR) << "Symlink creation failure: " << symlink_path; - return false; - } - - // Give an execution permission to the original executable - LOG(DEBUG) << "Giving exec permission to " << app->exec; - bf::permissions(bf::path(app->exec), bf::owner_all | - bf::group_read | bf::group_exe | - bf::others_read | bf::others_exe, boost_error); - if (boost_error) { - LOG(ERROR) << "Permission change failure"; - return false; - } - return true; -} - -} // namespace - -Status StepCreateSymbolicLink::precheck() { - manifest_x *m = context_->manifest_data.get(); - if (!m) { - LOG(ERROR) << "manifest_data attribute is empty"; - return Step::Status::INVALID_VALUE; - } - if (!m->application) { - LOG(ERROR) << "No application exists"; - return Step::Status::ERROR; - } - - return Step::Status::OK; -} - -Status StepCreateSymbolicLink::process() { - manifest_x* m = context_->manifest_data.get(); - for (application_x* app : GListRange(m->application)) { - if (!CreateSymLink(app, context_)) - return Status::ERROR; - } - return Status::OK; -} - - -Status StepCreateSymbolicLink::undo() { - manifest_x* m = context_->manifest_data.get(); - Step::Status ret = Status::OK; - for (application_x* app : GListRange(m->application)) { - if (!CreateSymLink(app, context_)) - ret = Status::ERROR; - } - return ret; -} - -} // namespace filesystem -} // namespace tpk diff --git a/src/tpk/step/step_create_symbolic_link.h b/src/tpk/step/step_create_symbolic_link.h deleted file mode 100644 index 0339cf7..0000000 --- a/src/tpk/step/step_create_symbolic_link.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */ -#ifndef TPK_STEP_STEP_CREATE_SYMBOLIC_LINK_H_ -#define TPK_STEP_STEP_CREATE_SYMBOLIC_LINK_H_ - -#include - -#include "common/app_installer.h" - -namespace tpk { -namespace filesystem { - -class StepCreateSymbolicLink : public common_installer::Step { - public: - using Step::Step; - Status process() override; - Status clean() override { return Status::OK; } - Status undo() override; - Status precheck() override; - - SCOPE_LOG_TAG(SymbolicLink) -}; - -} // namespace filesystem -} // namespace tpk - -#endif // TPK_STEP_STEP_CREATE_SYMBOLIC_LINK_H_ diff --git a/src/tpk/step/step_parse.cc b/src/tpk/step/step_parse.cc deleted file mode 100644 index 4085116..0000000 --- a/src/tpk/step/step_parse.cc +++ /dev/null @@ -1,671 +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 "tpk/step/step_parse.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common/app_installer.h" -#include "common/installer_context.h" -#include "common/step/step.h" -#include "common/utils/glist_range.h" - -namespace tpk { -namespace parse { - -namespace { - -namespace app_keys = tpk::application_keys; -namespace bf = boost::filesystem; - -const char kManifestFileName[] = "tizen-manifest.xml"; - -} // namepsace - -common_installer::Step::Status StepParse::precheck() { - if (context_->unpacked_dir_path.get().empty()) { - LOG(ERROR) << "unpacked_dir_path attribute is empty"; - return common_installer::Step::Status::INVALID_VALUE; - } - if (!boost::filesystem::exists(context_->unpacked_dir_path.get())) { - LOG(ERROR) << "unpacked_dir_path (" - << context_->unpacked_dir_path.get() - << ") path does not exist"; - return common_installer::Step::Status::INVALID_VALUE; - } - - boost::filesystem::path tmp; - if (!context_->xml_path.get().empty()) { - tmp = context_->xml_path.get(); - } else { - tmp = context_->unpacked_dir_path.get(); - tmp /= kManifestFileName; - } - - if (!boost::filesystem::exists(tmp)) { - LOG(ERROR) << "manifest not found from the package"; - return common_installer::Step::Status::INVALID_VALUE; - } - - return common_installer::Step::Status::OK; -} - -bool StepParse::LocateConfigFile() { - boost::filesystem::path manifest; - if (!context_->xml_path.get().empty()) { - manifest = context_->xml_path.get(); - } else { - manifest = context_->unpacked_dir_path.get(); - manifest /= kManifestFileName; - } - - LOG(DEBUG) << "manifest path: " << manifest; - - if (!boost::filesystem::exists(manifest)) - return false; - - path_ = manifest; - return true; -} - -bf::path StepParse::LocateConfigFile() const { - boost::filesystem::path path; - if (!context_->xml_path.get().empty()) { - path = context_->xml_path.get(); - } else { - path = context_->unpacked_dir_path.get(); - path /= kManifestFileName; - } - return path; -} - -bool StepParse::FillInstallationInfo(manifest_x* manifest) { - manifest->root_path = strdup( - (context_->root_application_path.get() / manifest->package).c_str()); - manifest->installed_time = - strdup(std::to_string(std::chrono::system_clock::to_time_t( - std::chrono::system_clock::now())).c_str()); - return true; -} - -bool StepParse::FillPackageInfo(manifest_x* manifest) { - std::shared_ptr pkg_info = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kManifestKey)); - if (!pkg_info) { - LOG(ERROR) << "Package info manifest data has not been found."; - return false; - } - - std::shared_ptr ui_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kUIApplicationKey)); - std::shared_ptr service_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kServiceApplicationKey)); - std::shared_ptr widget_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kWidgetApplicationKey)); - - // mandatory check - if (!ui_application_list && !service_application_list && - !widget_application_list) { - LOG(ERROR) << "UI Application or Service Application or Widget Application " - "are mandatory and has not been found."; - return false; - } - - manifest->ns = strdup(pkg_info->xmlns().c_str()); - manifest->package = strdup(pkg_info->package().c_str()); - manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str()); - manifest->type = strdup("tpk"); - manifest->appsetting = strdup("false"); - manifest->support_disable = strdup("false"); - manifest->version = strdup(pkg_info->version().c_str()); - manifest->installlocation = strdup(pkg_info->install_location().c_str()); - manifest->api_version = strdup(pkg_info->api_version().c_str()); - - for (auto& pair : pkg_info->labels()) { - label_x* label = reinterpret_cast(calloc(1, sizeof(label_x))); - if (!pair.first.empty()) - label->lang = strdup(pair.first.c_str()); - else - label->lang = strdup(DEFAULT_LOCALE); - label->name = strdup(pair.second.c_str()); - manifest->label = g_list_append(manifest->label, label); - } - - std::shared_ptr profile_info = - std::static_pointer_cast( - parser_->GetManifestData(ProfileInfo::Key())); - if (profile_info) { - for (auto& profile : profile_info->profiles()) { - manifest->deviceprofile = g_list_append(manifest->deviceprofile, - strdup(profile.c_str())); - } - } - - if (ui_application_list) { - manifest->mainapp_id = - strdup(ui_application_list->items[0].ui_info.appid().c_str()); - } else if (service_application_list) { - manifest->mainapp_id = - strdup(service_application_list->items[0].sa_info.appid().c_str()); - } else if (widget_application_list) { - manifest->mainapp_id = - strdup(widget_application_list->items[0].widget_info.appid().c_str()); - } - return true; -} - -bool StepParse::FillAuthorInfo(manifest_x* manifest) { - std::shared_ptr author_info = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kAuthorKey)); - - if (!author_info) { - LOG(ERROR) << "Author data has not been found."; - return false; - } - - author_x* author = reinterpret_cast(calloc(1, sizeof(author_x))); - author->text = strdup(author_info->name().c_str()); - author->email = strdup(author_info->email().c_str()); - author->href = strdup(author_info->href().c_str()); - author->lang = strdup(DEFAULT_LOCALE); - manifest->author = g_list_append(manifest->author, author); - return true; -} - -bool StepParse::FillDescription(manifest_x* manifest) { - std::shared_ptr description_info = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kDescriptionKey)); - - if (!description_info) { - LOG(ERROR) << "Description data has not been found."; - return false; - } - - description_x* description = reinterpret_cast - (calloc(1, sizeof(description_x))); - description->text = strdup(description_info->description().c_str()); - description->lang = !description_info->xml_lang().empty() ? - strdup(description_info->xml_lang().c_str()) : strdup(DEFAULT_LOCALE); - manifest->description = g_list_append(manifest->description, description); - return true; -} - -bool StepParse::FillPrivileges(manifest_x* manifest) { - std::shared_ptr perm_info = - std::static_pointer_cast(parser_->GetManifestData( - app_keys::kPrivilegesKey)); - if (!perm_info) - return true; - - std::set privileges = perm_info->GetPrivileges(); - for (auto& priv : privileges) { - manifest->privileges = g_list_append(manifest->privileges, - strdup(priv.c_str())); - } - return true; -} - -bool StepParse::FillWidgetApplication(manifest_x* manifest) { - std::shared_ptr widget_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kWidgetApplicationKey)); - if (!widget_application_list) - return true; - - for (const auto& application : widget_application_list->items) { - // if there is no app yet, set this app as mainapp - bool main_app = manifest->application == nullptr; - - application_x* widget_app = - static_cast(calloc(1, sizeof(application_x))); - widget_app->appid = strdup(application.widget_info.appid().c_str()); - widget_app->exec = strdup((context_->root_application_path.get() - / manifest->package / "bin" - / application.widget_info.exec()).c_str()); - widget_app->launch_mode = - strdup(application.widget_info.launch_mode().c_str()); - widget_app->multiple = strdup(application.widget_info.multiple().c_str()); - widget_app->nodisplay = - strdup(application.widget_info.nodisplay().c_str()); - widget_app->type = strdup("capp"); - widget_app->component_type = strdup("widgetapp"); - widget_app->hwacceleration = - strdup(application.widget_info.hwacceleration().c_str()); - widget_app->onboot = strdup("false"); - widget_app->autorestart = strdup("false"); - widget_app->mainapp = main_app ? strdup("true") : strdup("false"); - widget_app->enabled = strdup("true"); - widget_app->screenreader = strdup("use-system-setting"); - widget_app->recentimage = strdup("false"); - widget_app->launchcondition = strdup("false"); - widget_app->guestmode_visibility = strdup("true"); - widget_app->permission_type = strdup("normal"); - widget_app->ambient_support = strdup("false"); - widget_app->package = strdup(manifest->package); - widget_app->support_disable = strdup(manifest->support_disable); - manifest->application = g_list_append(manifest->application, widget_app); - - if (!FillApplicationIconPaths(widget_app, application.app_icons)) - return false; - if (!FillLabel(widget_app, application.label)) - return false; - if (!FillImage(widget_app, application.app_images)) - return false; - if (!FillMetadata(widget_app, application.meta_data)) - return false; - } - return true; -} - -bool StepParse::FillServiceApplication(manifest_x* manifest) { - std::shared_ptr service_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kServiceApplicationKey)); - if (!service_application_list) - return true; - - for (const auto& application : service_application_list->items) { - // if there is no app yet, set this app as mainapp - bool main_app = manifest->application == nullptr; - - application_x* service_app = - static_cast(calloc(1, sizeof(application_x))); - service_app->appid = strdup(application.sa_info.appid().c_str()); - service_app->autorestart = - strdup(application.sa_info.auto_restart().c_str()); - service_app->exec = strdup((context_->root_application_path.get() - / manifest->package / "bin" - / application.sa_info.exec()).c_str()); - service_app->onboot = strdup(application.sa_info.on_boot().c_str()); - service_app->type = strdup(application.sa_info.type().c_str()); - service_app->process_pool = - strdup(application.sa_info.process_pool().c_str()); - service_app->component_type = strdup("svcapp"); - service_app->mainapp = main_app ? strdup("true") : strdup("false"); - service_app->enabled = strdup("true"); - service_app->hwacceleration = strdup("default"); - service_app->screenreader = strdup("use-system-setting"); - service_app->recentimage = strdup("false"); - service_app->launchcondition = strdup("false"); - service_app->indicatordisplay = strdup("true"); - service_app->effectimage_type = strdup("image"); - service_app->guestmode_visibility = strdup("true"); - service_app->permission_type = strdup("normal"); - service_app->submode = strdup("false"); - service_app->process_pool = strdup("false"); - service_app->ambient_support = strdup("false"); - service_app->package = strdup(manifest->package); - service_app->support_disable = strdup(manifest->support_disable); - manifest->application = g_list_append(manifest->application, service_app); - - if (!FillAppControl(service_app, application.app_control)) - return false; - if (!FillDataControl(service_app, application.data_control)) - return false; - if (!FillApplicationIconPaths(service_app, application.app_icons)) - return false; - if (!FillLabel(service_app, application.label)) - return false; - if (!FillMetadata(service_app, application.meta_data)) - return false; - if (!FillBackgroundCategoryInfo(service_app, - application.background_category)) - return false; - } - return true; -} - -bool StepParse::FillUIApplication(manifest_x* manifest) { - std::shared_ptr ui_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kUIApplicationKey)); - if (!ui_application_list) - return true; - - for (const auto& application : ui_application_list->items) { - // if there is no app yet, set this app as mainapp - bool main_app = manifest->application == nullptr; - - application_x* ui_app = - static_cast(calloc(1, sizeof(application_x))); - ui_app->appid = strdup(application.ui_info.appid().c_str()); - ui_app->exec = strdup((context_->root_application_path.get() - / manifest->package / "bin" - / application.ui_info.exec()).c_str()); - ui_app->launch_mode = strdup(application.ui_info.launch_mode().c_str()); - ui_app->multiple = strdup(application.ui_info.multiple().c_str()); - ui_app->nodisplay = strdup(application.ui_info.nodisplay().c_str()); - ui_app->taskmanage = strdup(application.ui_info.taskmanage().c_str()); - ui_app->type = strdup(application.ui_info.type().c_str()); - ui_app->component_type = strdup("uiapp"); - ui_app->ui_gadget = strdup(application.ui_info.uigadget().c_str()); - ui_app->process_pool = strdup(application.ui_info.process_pool().c_str()); - ui_app->submode = strdup(application.ui_info.submode().c_str()); - ui_app->indicatordisplay = - strdup(application.ui_info.indicator_display().c_str()); - ui_app->effectimage_type = - strdup(application.ui_info.effectimage_type().c_str()); - ui_app->portraitimg = - strdup(application.ui_info.portrait_image().c_str()); - ui_app->landscapeimg = - strdup(application.ui_info.landscape_image().c_str()); - ui_app->submode_mainid = - strdup(application.ui_info.submode_mainid().c_str()); - ui_app->hwacceleration = - strdup(application.ui_info.hwacceleration().c_str()); - ui_app->onboot = strdup("false"); - ui_app->autorestart = strdup("false"); - ui_app->component_type = strdup("uiapp"); - ui_app->mainapp = main_app ? strdup("true") : strdup("false"); - ui_app->enabled = strdup("true"); - ui_app->screenreader = strdup("use-system-setting"); - ui_app->recentimage = strdup("false"); - ui_app->launchcondition = strdup("false"); - ui_app->guestmode_visibility = strdup("true"); - ui_app->permission_type = strdup("normal"); - ui_app->ambient_support = strdup("false"); - ui_app->package = strdup(manifest->package); - ui_app->support_disable = strdup(manifest->support_disable); - manifest->application = g_list_append(manifest->application, ui_app); - - if (!FillAppControl(ui_app, application.app_control)) - return false; - if (!FillDataControl(ui_app, application.data_control)) - return false; - if (!FillApplicationIconPaths(ui_app, application.app_icons)) - return false; - if (!FillLabel(ui_app, application.label)) - return false; - if (!FillImage(ui_app, application.app_images)) - return false; - if (!FillMetadata(ui_app, application.meta_data)) - return false; - if (!FillBackgroundCategoryInfo(ui_app, application.background_category)) - return false; - } - return true; -} - -template -bool StepParse::FillAppControl(application_x* app, const T& app_control_list) { - if (app_control_list.empty()) - return true; - - for (const auto& control : app_control_list) { - appcontrol_x* app_control = - static_cast(calloc(1, sizeof(appcontrol_x))); - app_control->operation = strdup(control.operation().c_str()); - if (!control.mime().empty()) - app_control->mime = strdup(control.mime().c_str()); - if (!control.uri().empty()) - app_control->uri = strdup(control.uri().c_str()); - app->appcontrol = g_list_append(app->appcontrol, app_control); - } - return true; -} - -template -bool StepParse::FillDataControl(application_x* app, - const T& data_control_list) { - if (data_control_list.empty()) - return true; - - for (const auto& control : data_control_list) { - datacontrol_x* data_control = - static_cast(calloc(1, sizeof(datacontrol_x))); - data_control->access = strdup(control.access().c_str()); - data_control->providerid = strdup(control.providerid().c_str()); - data_control->type = strdup(control.type().c_str()); - app->datacontrol = g_list_append(app->datacontrol, data_control); - } - return true; -} - -template -bool StepParse::FillApplicationIconPaths(application_x* app, - const T& icons_info) { - for (auto& application_icon : icons_info.icons()) { - icon_x* icon = reinterpret_cast (calloc(1, sizeof(icon_x))); - // NOTE: name is an attribute, but the xml writer uses it as text. - // This must be fixed in whole app-installer modules, including wgt. - // Current implementation is just for compatibility. - icon->text = strdup(application_icon.path().c_str()); - icon->name = strdup(application_icon.path().c_str()); - icon->lang = strdup(DEFAULT_LOCALE); - app->icon = g_list_append(app->icon, icon); - } - return true; -} - -template -bool StepParse::FillLabel(application_x* app, const T& label_list) { - if (label_list.empty()) - return true; - - for (const auto& control : label_list) { - label_x* label = - static_cast(calloc(1, sizeof(label_x))); - // NOTE: name is an attribute, but the xml writer uses it as text. - // This must be fixed in whole app-installer modules, including wgt. - // Current implementation is just for compatibility. - label->text = strdup(control.text().c_str()); - label->name = strdup(control.name().c_str()); - label->lang = !control.xml_lang().empty() ? - strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE); - app->label = g_list_append(app->label, label); - } - return true; -} - -template -bool StepParse::FillMetadata(application_x* app, const T& meta_data_list) { - if (meta_data_list.empty()) - return true; - - for (auto& meta : meta_data_list) { - metadata_x* metadata = - static_cast(calloc(1, sizeof(metadata_x))); - metadata->key = strdup(meta.key().c_str()); - metadata->value = strdup(meta.val().c_str()); - app->metadata = g_list_append(app->metadata, metadata); - } - return true; -} - -bool StepParse::FillImage(application_x* app, - const tpk::parse::ApplicationImagesInfo& image_list) { - for (auto& app_image : image_list.images) { - image_x* image = - static_cast(calloc(1, sizeof(image_x))); - image->name = strdup(app_image.name().c_str()); - const std::string& lang = app_image.lang(); - if (!lang.empty()) - image->lang = strdup(lang.c_str()); - else - image->lang = strdup(DEFAULT_LOCALE); - if (!app_image.section().empty()) - image->section = strdup(app_image.section().c_str()); - app->image = g_list_append(app->image, image); - } - return true; -} - -bool StepParse::FillAccounts() { - std::shared_ptr account_info = - std::static_pointer_cast(parser_->GetManifestData( - app_keys::kAccountKey)); - if (!account_info) - return true; - - common_installer::AccountInfo info; - for (auto& account : account_info->accounts()) { - common_installer::SingleAccountInfo single_info; - single_info.capabilities = account.capabilities; - single_info.icon_paths = account.icon_paths; - single_info.multiple_account_support = account.multiple_account_support; - single_info.names = account.labels; - // appid has the same value as package - single_info.appid = account.app_id; - single_info.providerid = account.provider_id; - info.set_account(single_info); - } - context_->manifest_plugins_data.get().account_info.set(info); - return true; -} - -bool StepParse::FillShortcuts() { - std::shared_ptr shortcut_info = - std::static_pointer_cast(parser_->GetManifestData( - app_keys::kShortcutListKey)); - if (!shortcut_info) - return true; - - common_installer::ShortcutListInfo list; - for (auto& shortcut : shortcut_info->shortcuts) { - common_installer::ShortcutInfo single_info; - single_info.app_id = shortcut.app_id; - single_info.extra_data = shortcut.extra_data; - single_info.extra_key = shortcut.extra_key; - single_info.icon = shortcut.icon; - single_info.labels = shortcut.labels; - list.push_back(single_info); - } - context_->manifest_plugins_data.get().shortcut_info.set(list); - return true; -} - -template -bool StepParse::FillBackgroundCategoryInfo(application_x* app, - const T& background_category_data_list) { - for (const auto& background_category : background_category_data_list) { - app->background_category = g_list_append( - app->background_category, strdup(background_category.value().c_str())); - } - - return true; -} - -bool StepParse::FillManifestX(manifest_x* manifest) { - if (!FillPackageInfo(manifest)) - return false; - if (!FillInstallationInfo(manifest)) - return false; - if (!FillUIApplication(manifest)) - return false; - if (!FillServiceApplication(manifest)) - return false; - if (!FillWidgetApplication(manifest)) - return false; - if (!FillPrivileges(manifest)) - return false; - if (!FillAccounts()) - return false; - if (!FillShortcuts()) - return false; - return true; -} - -common_installer::Step::Status StepParse::process() { - if (!LocateConfigFile()) { - LOG(ERROR) << "No manifest file exists"; - return common_installer::Step::Status::ERROR; - } - parser_.reset(new tpk::parse::TPKConfigParser()); - if (!parser_->ParseManifest(path_)) { - LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage(); - return common_installer::Step::Status::ERROR; - } - - manifest_x* manifest = - static_cast(calloc(1, sizeof(manifest_x))); - - if (!FillManifestX(const_cast(manifest))) { - LOG(ERROR) << "[Parse] Storing manifest_x failed. " - << parser_->GetErrorMessage(); - return common_installer::Step::Status::ERROR; - } - - if (!context_->tep_path.get().empty()) - manifest->tep_name = context_->tep_path.get().c_str(); - - // Copy data from ManifestData to InstallerContext - std::shared_ptr info = - std::static_pointer_cast( - parser_->GetManifestData( - app_keys::kManifestKey)); - - context_->pkgid.set(manifest->package); - - // write pkgid for recovery file - if (context_->recovery_info.get().recovery_file) { - context_->recovery_info.get().recovery_file->set_pkgid(manifest->package); - context_->recovery_info.get().recovery_file->WriteAndCommitFileContent(); - } - - std::shared_ptr perm_info = - std::static_pointer_cast( - parser_->GetManifestData( - application_keys::kPrivilegesKey)); - parser::PrivilegesSet privileges; - if (perm_info) - privileges = perm_info->GetPrivileges(); - - std::shared_ptr ui_application_list = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kUIApplicationKey)); - - LOG(DEBUG) << " Read data -[ "; - LOG(DEBUG) << "App package: " << info->package(); - LOG(DEBUG) << " aplication version = " << info->version(); - LOG(DEBUG) << " api_version = " << info->api_version(); - if (ui_application_list) { - LOG(DEBUG) << " launch_modes -["; - for (const auto& application : ui_application_list->items) { - LOG(DEBUG) << " launch_mode[" << application.ui_info.appid() << "] = " - << application.ui_info.launch_mode(); - } - } - LOG(DEBUG) << " ]-"; - LOG(DEBUG) << " privileges -["; - for (const auto& p : privileges) { - LOG(DEBUG) << " " << p; - } - LOG(DEBUG) << " ]-"; - LOG(DEBUG) << "]-"; - - context_->manifest_data.set(manifest); - return common_installer::Step::Status::OK; -} - -} // namespace parse -} // namespace tpk diff --git a/src/tpk/step/step_parse.h b/src/tpk/step/step_parse.h deleted file mode 100644 index b1ccc4e..0000000 --- a/src/tpk/step/step_parse.h +++ /dev/null @@ -1,81 +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 TPK_STEP_STEP_PARSE_H_ -#define TPK_STEP_STEP_PARSE_H_ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "common/app_installer.h" -#include "common/installer_context.h" -#include "common/step/step.h" - -namespace tpk { -namespace parse { - -class StepParse : public common_installer::Step { - public: - using Step::Step; - explicit StepParse(common_installer::InstallerContext* context, - bool check_start_file); - - Status process() override; - Status clean() override { return Status::OK; } - Status undo() override { return Status::OK; } - Status precheck() override; - - protected: - virtual bool LocateConfigFile(); - // This function is needed by recovery mode to override searching - // of configuration file of the package - virtual boost::filesystem::path LocateConfigFile() const; - boost::filesystem::path path_; - - private: - bool FillInstallationInfo(manifest_x* manifest); - bool FillPackageInfo(manifest_x* manifest); - bool FillAuthorInfo(manifest_x* manifest); - bool FillDescription(manifest_x* manifest); - bool FillPrivileges(manifest_x* manifest); - bool FillWidgetApplication(manifest_x* manifest); - bool FillServiceApplication(manifest_x* manifest); - bool FillUIApplication(manifest_x* manifest); - template - bool FillAppControl(application_x* manifest, const T& app_control_list); - template - bool FillDataControl(application_x* manifest, const T& data_control_list); - template - bool FillApplicationIconPaths(application_x* manifest, - const T& icons_info); - template - bool FillLabel(application_x* manifest, const T& label_list); - template - bool FillMetadata(application_x* manifest, const T& meta_data_list); - bool FillImage(application_x* app, - const tpk::parse::ApplicationImagesInfo& label_list); - bool FillAccounts(); - bool FillShortcuts(); - template - bool FillBackgroundCategoryInfo(application_x* app, - const T& background_category_data_list); - bool FillManifestX(manifest_x* manifest); - - std::unique_ptr parser_; - - SCOPE_LOG_TAG(Parse) -}; - -} // namespace parse -} // namespace tpk - -#endif // TPK_STEP_STEP_PARSE_H_ diff --git a/src/tpk/step/step_parse_recovery.cc b/src/tpk/step/step_parse_recovery.cc deleted file mode 100644 index da0fd29..0000000 --- a/src/tpk/step/step_parse_recovery.cc +++ /dev/null @@ -1,55 +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 "tpk/step/step_parse_recovery.h" - -#include - -#include "common/backup_paths.h" - -namespace bf = boost::filesystem; - -namespace { - -const char kManifestFileName[] = "tizen-manifest.xml"; - -} // namespace - -namespace tpk { -namespace parse { - -common_installer::Step::Status StepParseRecovery::process() { - (void) StepParse::process(); - return Status::OK; -} - - -common_installer::Step::Status StepParseRecovery::precheck() { - if (context_->root_application_path.get().empty()) { - LOG(ERROR) << "Root path of packages in not set"; - return Status::ERROR; - } - if (context_->pkgid.get().empty()) { - LOG(WARNING) << "Pkgid is not set. Parsing skipped"; - return Status::OK; - } - return Status::OK; -} - -boost::filesystem::path StepParseRecovery::LocateConfigFile() const { - context_->pkg_path.set( - context_->root_application_path.get() / context_->pkgid.get()); - bf::path path1 = common_installer::GetBackupPathForPackagePath( - context_->pkg_path.get()) / kManifestFileName; - bf::path path2 = context_->pkg_path.get() / kManifestFileName; - if (bf::exists(path1)) - return path1; - if (bf::exists(path2)) - return path2; - return {}; -} - -} // namespace parse -} // namespace tpk - diff --git a/src/tpk/step/step_parse_recovery.h b/src/tpk/step/step_parse_recovery.h deleted file mode 100644 index 5522ed0..0000000 --- a/src/tpk/step/step_parse_recovery.h +++ /dev/null @@ -1,32 +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 TPK_STEP_STEP_PARSE_RECOVERY_H_ -#define TPK_STEP_STEP_PARSE_RECOVERY_H_ - -#include - -#include - -#include "tpk/step/step_parse.h" - -namespace tpk { -namespace parse { - -class StepParseRecovery : public StepParse { - public: - using StepParse::StepParse; - - Status process() override; - Status precheck() override; - - protected: - boost::filesystem::path LocateConfigFile() const override; - - SCOPE_LOG_TAG(ParseRecovery) -}; -} // namespace parse -} // namespace tpk - -#endif // TPK_STEP_STEP_PARSE_RECOVERY_H_ diff --git a/src/tpk/tpk_app_query_interface.cc b/src/tpk/tpk_app_query_interface.cc deleted file mode 100644 index 228aea7..0000000 --- a/src/tpk/tpk_app_query_interface.cc +++ /dev/null @@ -1,119 +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 "tpk/tpk_app_query_interface.h" - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "common/pkgmgr_registration.h" -#include "common/request.h" -#include "common/utils/file_util.h" - -namespace bf = boost::filesystem; -namespace bs = boost::system; -namespace ci = common_installer; - -namespace { - -const char kManifestFileName[] = "tizen-manifest.xml"; - -std::string GetInstallationPackagePath(int argc, char** argv) { - std::string path; - for (int i = 0; i < argc; ++i) { - if (!strcmp(argv[i], "-i")) { - if (i + 1 < argc) { - path = argv[i + 1]; - break; - } - } - } - return path; -} - -std::string GetXmlPath(int argc, char** argv) { - std::string path; - for (int i = 0; i < argc; ++i) { - if (!strcmp(argv[i], "-x")) { - if (i + 1 < argc) { - path = argv[i + 1]; - break; - } - } - } - return path; -} - -std::string GetPkgIdFromXml(const std::string&path) { - bf::path xml_path(path); - - return xml_path.stem().string(); -} - -std::string GetPkgIdFromPath(const std::string& path) { - bf::path tmp_path = common_installer::GenerateTmpDir("/tmp"); - bs::error_code code; - bf::create_directories(tmp_path, code); - if (code) - return {}; - if (!common_installer::ExtractToTmpDir(path.c_str(), tmp_path, - kManifestFileName)) { - bf::remove_all(tmp_path, code); - return {}; - } - bf::path manifest_path = tmp_path / kManifestFileName; - if (!bf::exists(manifest_path)) { - bf::remove_all(tmp_path, code); - return {}; - } - - tpk::parse::TPKConfigParser parser; - if (!parser.ParseManifest(manifest_path)) - return {}; - auto package_info = std::static_pointer_cast( - parser.GetManifestData(tpk::application_keys::kManifestKey)); - if (!package_info) - return {}; - std::string pkg_id = package_info->package(); - bf::remove_all(tmp_path, code); - return pkg_id; -} - -} // namespace - -namespace tpk { - -bool TpkAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) { - std::string path = GetInstallationPackagePath(argc, argv); - std::string pkg_id; - if (path.empty()) { - // check if it is manifest direct install - path = GetXmlPath(argc, argv); - if (path.empty()) - return false; - - pkg_id = GetPkgIdFromXml(path); - } else { - pkg_id = GetPkgIdFromPath(path); - } - - if (pkg_id.empty()) - return false; - return ci::IsPackageInstalled(pkg_id, ci::GetRequestMode()); -} - -} // namespace tpk - diff --git a/src/tpk/tpk_app_query_interface.h b/src/tpk/tpk_app_query_interface.h deleted file mode 100644 index bfe2a14..0000000 --- a/src/tpk/tpk_app_query_interface.h +++ /dev/null @@ -1,19 +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 TPK_TPK_APP_QUERY_INTERFACE_H_ -#define TPK_TPK_APP_QUERY_INTERFACE_H_ - -#include "common/app_query_interface.h" - -namespace tpk { - -class TpkAppQueryInterface : public common_installer::AppQueryInterface { - public: - bool IsAppInstalledByArgv(int argc, char** argv) override; -}; - -} // namespace tpk - -#endif // TPK_TPK_APP_QUERY_INTERFACE_H_ diff --git a/src/tpk/tpk_backend.cc b/src/tpk/tpk_backend.cc deleted file mode 100644 index 2df73d0..0000000 --- a/src/tpk/tpk_backend.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */ - -#include - -#include - -#include "common/pkgmgr_interface.h" -#include "tpk/tpk_app_query_interface.h" -#include "tpk/tpk_installer.h" - -namespace ci = common_installer; - -int main(const int argc, char* argv[]) { - tpk::TpkAppQueryInterface interface; - ci::PkgMgrPtr pkgmgr = ci::PkgMgrInterface::Create(argc, argv, &interface); - if (!pkgmgr) { - LOG(ERROR) << "Failed to create pkgmgr interface"; - return -1; - } - tpk::TpkInstaller t(pkgmgr); - if (t.Run() != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "TpkInstaller run failure"; - return -1; - } - return 0; -} diff --git a/src/tpk/tpk_installer.cc b/src/tpk/tpk_installer.cc deleted file mode 100644 index 65cb108..0000000 --- a/src/tpk/tpk_installer.cc +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */ -#include "tpk/tpk_installer.h" -#include "common/app_installer.h" -#include "common/step/step_configure.h" -#include "common/step/step_backup_icons.h" -#include "common/step/step_backup_manifest.h" -#include "common/step/step_create_icons.h" -#include "common/step/step_create_storage_directories.h" -#include "common/step/step_copy.h" -#include "common/step/step_copy_tep.h" -#include "common/step/step_copy_backup.h" -#include "common/step/step_check_old_certificate.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_open_recovery_file.h" -#include "common/step/step_parse.h" -#include "common/step/step_privilege_compatibility.h" -#include "common/step/step_recover_application.h" -#include "common/step/step_recover_files.h" -#include "common/step/step_recover_icons.h" -#include "common/step/step_recover_manifest.h" -#include "common/step/step_recover_security.h" -#include "common/step/step_recover_storage_directories.h" -#include "common/step/step_register_app.h" -#include "common/step/step_remove_icons.h" -#include "common/step/step_remove_files.h" -#include "common/step/step_revoke_security.h" -#include "common/step/step_remove_temporary_directory.h" -#include "common/step/step_register_security.h" -#include "common/step/step_rollback_deinstallation_security.h" -#include "common/step/step_rollback_installation_security.h" -#include "common/step/step_check_signature.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 "common/step/step_update_tep.h" -#include "tpk/step/step_check_tpk_background_category.h" -#include "tpk/step/step_create_symbolic_link.h" -#include "tpk/step/step_parse.h" -#include "tpk/step/step_parse_recovery.h" -#include "tpk/step/step_convert_xml.h" - -namespace ci = common_installer; - -namespace { - -const char kPkgType[] = "tpk"; - -} // namespace - -namespace tpk { - -TpkInstaller::TpkInstaller(common_installer::PkgMgrPtr pkgmgr) - : AppInstaller(kPkgType, pkgmgr) { - Prepare(); -} - -TpkInstaller::~TpkInstaller() { -} - -void TpkInstaller::Prepare() { - switch (pkgmgr_->GetRequestType()) { - case ci::RequestType::Install: - InstallSteps(); - break; - case ci::RequestType::Update: - UpdateSteps(); - break; - case ci::RequestType::Uninstall: - UninstallSteps(); - break; - case ci::RequestType::Reinstall: - ReinstallSteps(); - break; - case ci::RequestType::Delta: - DeltaSteps(); - break; - case ci::RequestType::Recovery: - RecoverySteps(); - break; - case ci::RequestType::ManifestDirectInstall: - ManifestDirectInstallSteps(); - break; - case ci::RequestType::ManifestDirectUpdate: - ManifestDirectUpdateSteps(); - break; - default: - AddStep(); - break; - } -} - -void TpkInstaller::InstallSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - -void TpkInstaller::UpdateSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - // TODO(t.iwanek): handle coping storage directories - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - /* TODO(jungh.yeon): this temporary step will be removed - * when secondary parsing procedure has removed*/ - AddStep(); -} - -void TpkInstaller::UninstallSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - -void TpkInstaller::ReinstallSteps() { - AddStep(); -} - -void TpkInstaller::DeltaSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - // TODO(t.iwanek): handle coping storage directories - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - -void TpkInstaller::RecoverySteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - -void TpkInstaller::ManifestDirectInstallSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - -void TpkInstaller::ManifestDirectUpdateSteps() { - AddStep(pkgmgr_); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); - AddStep(); -} - - -} // namespace tpk - diff --git a/src/tpk/tpk_installer.h b/src/tpk/tpk_installer.h deleted file mode 100644 index 43acab5..0000000 --- a/src/tpk/tpk_installer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */ - -#ifndef TPK_TPK_INSTALLER_H_ -#define TPK_TPK_INSTALLER_H_ - -#include - -#include "common/app_installer.h" -#include "common/pkgmgr_interface.h" - -namespace tpk { - -/** - * @brief The TpkInstaller class - * Handles request of tpk packages. - * - * This class is main class for installation/update/deinstallation of tpk - * packages. Pkgmgr request is parsed within and sequence of steps is built to - * be run. - */ -class TpkInstaller : public common_installer::AppInstaller { - public: - explicit TpkInstaller(common_installer::PkgMgrPtr pkgmgr); - ~TpkInstaller(); - void Prepare(); - - private: - void InstallSteps(); - void UpdateSteps(); - void UninstallSteps(); - void ReinstallSteps(); - void DeltaSteps(); - void RecoverySteps(); - void ManifestDirectInstallSteps(); - void ManifestDirectUpdateSteps(); - - SCOPE_LOG_TAG(TpkInstaller) -}; - -} // namespace tpk - -#endif // TPK_TPK_INSTALLER_H_ diff --git a/src/unit_tests/CMakeLists.txt b/src/unit_tests/CMakeLists.txt index 54f33fa..fab013c 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -1,7 +1,3 @@ -SET(TESTS - signature_unittest - smoke_test -) SET(DESTINATION_DIR app-installers-ut) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../) @@ -10,27 +6,17 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../) ADD_EXECUTABLE(signature_unittest signature_unittest.cc ) -ADD_EXECUTABLE(smoke_test - smoke_test.cc -) INSTALL(DIRECTORY test_samples/ DESTINATION ${SHAREDIR}/${DESTINATION_DIR}/test_samples) -INSTALL(FILES run-unit-tests.sh DESTINATION ${BINDIR}/app-installers-ut/ - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ) -FOREACH(test ${TESTS}) -APPLY_PKG_CONFIG(${test} PUBLIC +APPLY_PKG_CONFIG(signature_unittest PUBLIC Boost GTEST ) -ENDFOREACH(test) # FindGTest module do not sets all needed libraries in GTEST_LIBRARIES and # GTest main libraries is still missing, so additional linking of # GTEST_MAIN_LIBRARIES is needed. target_link_libraries(signature_unittest PUBLIC ${TARGET_LIBNAME_COMMON} ${GTEST_MAIN_LIBRARIES} pthread) -target_link_libraries(smoke_test PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_TPK} pthread) -FOREACH(test ${TESTS}) - INSTALL(TARGETS ${test} DESTINATION ${BINDIR}/${DESTINATION_DIR}) -ENDFOREACH(test) +INSTALL(TARGETS signature_unittest DESTINATION ${BINDIR}/${DESTINATION_DIR}) diff --git a/src/unit_tests/run-unit-tests.sh b/src/unit_tests/run-unit-tests.sh deleted file mode 100755 index 26db6c3..0000000 --- a/src/unit_tests/run-unit-tests.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -test_dir="`dirname $0`/*" -for file in $test_dir -do - if test -f "$file"; then - if [[ -x "$file" && ${file: -3} != ".sh" ]]; then - $file --gtest_output=xml:$file.xml - fi - fi -done diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc deleted file mode 100644 index 29a0973..0000000 --- a/src/unit_tests/smoke_test.cc +++ /dev/null @@ -1,587 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common/backup_paths.h" -#include "common/pkgmgr_interface.h" -#include "common/pkgmgr_registration.h" -#include "common/request.h" -#include "common/step/step_fail.h" -#include "tpk/tpk_app_query_interface.h" -#include "tpk/tpk_installer.h" -#include "wgt/wgt_app_query_interface.h" -#include "wgt/wgt_installer.h" - -#define SIZEOFARRAY(ARR) \ - sizeof(ARR) / sizeof(ARR[0]) \ - -namespace bf = boost::filesystem; -namespace bs = boost::system; -namespace ci = common_installer; - -namespace { - -const char kApplicationDir[] = ".applications"; -const char kApplicationDirBackup[] = ".applications.bck"; -const char KUserAppsDir[] = "apps_rw"; -const char KUserAppsDirBackup[] = "apps_rw.bck"; - -enum class RequestResult { - NORMAL, - FAIL, - CRASH -}; - -enum class PackageType { - TPK, - WGT -}; - -class StepCrash : public ci::Step { - public: - using Step::Step; - - ci::Step::Status process() override { - raise(SIGSEGV); - return Status::OK; - } - ci::Step::Status clean() override { return ci::Step::Status::OK; } - ci::Step::Status undo() override { return ci::Step::Status::OK; } - ci::Step::Status precheck() override { return ci::Step::Status::OK; } -}; - -void RemoveAllRecoveryFiles() { - bf::path root_path = ci::GetRootAppPath(); - for (auto& dir_entry : boost::make_iterator_range( - bf::directory_iterator(root_path), bf::directory_iterator())) { - if (bf::is_regular_file(dir_entry)) { - if (dir_entry.path().string().find("/recovery") != std::string::npos) { - bs::error_code error; - bf::remove(dir_entry.path(), error); - } - } - } -} - -bf::path FindRecoveryFile() { - bf::path root_path = ci::GetRootAppPath(); - for (auto& dir_entry : boost::make_iterator_range( - bf::directory_iterator(root_path), bf::directory_iterator())) { - if (bf::is_regular_file(dir_entry)) { - if (dir_entry.path().string().find("/recovery") != std::string::npos) { - return dir_entry.path(); - } - } - } - return {}; -} - -bool ValidateFileContentInPackage(const std::string& pkgid, - const std::string& relative, - const std::string& expected) { - bf::path root_path = ci::GetRootAppPath(); - bf::path file_path = root_path / pkgid / relative; - if (!bf::exists(file_path)) { - LOG(ERROR) << file_path << " doesn't exist"; - return false; - } - FILE* handle = fopen(file_path.c_str(), "r"); - if (!handle) { - LOG(ERROR) << file_path << " cannot be open"; - return false; - } - std::string content; - std::array buffer; - while (fgets(buffer.data(), buffer.size(), handle)) { - content += buffer.data(); - } - fclose(handle); - return content == expected; -} - -void ValidatePackageFS(const std::string& pkgid, const std::string& appid, - PackageType type) { - bf::path root_path = ci::GetRootAppPath(); - bf::path package_path = root_path / pkgid; - bf::path binary_path = package_path / "bin" / appid; - bf::path data_path = package_path / "data"; - bf::path shared_path = package_path / "shared"; - bf::path cache_path = package_path / "cache"; - ASSERT_TRUE(bf::exists(root_path)); - ASSERT_TRUE(bf::exists(package_path)); - ASSERT_TRUE(bf::exists(binary_path)); - ASSERT_TRUE(bf::exists(data_path)); - ASSERT_TRUE(bf::exists(shared_path)); - ASSERT_TRUE(bf::exists(cache_path)); - - bf::path manifest_path = - bf::path(getUserManifestPath(getuid())) / (pkgid + ".xml"); - bf::path icon_path = bf::path(getIconPath(getuid())) / (appid + ".png"); - ASSERT_TRUE(bf::exists(manifest_path)); - ASSERT_TRUE(bf::exists(icon_path)); - - if (type == PackageType::WGT) { - bf::path widget_root_path = package_path / "res" / "wgt"; - bf::path config_path = widget_root_path / "config.xml"; - ASSERT_TRUE(bf::exists(widget_root_path)); - ASSERT_TRUE(bf::exists(config_path)); - - bf::path private_tmp_path = package_path / "tmp"; - ASSERT_TRUE(bf::exists(private_tmp_path)); - } - - // backups should not exist - bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); - bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); - bf::path icon_backup = ci::GetBackupPathForIconFile(icon_path); - ASSERT_FALSE(bf::exists(package_backup)); - ASSERT_FALSE(bf::exists(manifest_backup)); - ASSERT_FALSE(bf::exists(icon_backup)); -} - -void PackageCheckCleanup(const std::string& pkgid, const std::string& appid) { - bf::path root_path = ci::GetRootAppPath(); - bf::path package_path = root_path / pkgid; - ASSERT_FALSE(bf::exists(package_path)); - - bf::path manifest_path = - bf::path(getUserManifestPath(getuid())) / (pkgid + ".xml"); - bf::path icon_path = bf::path(getIconPath(getuid())) / (appid + ".png"); - ASSERT_FALSE(bf::exists(manifest_path)); - ASSERT_FALSE(bf::exists(icon_path)); - - // backups should not exist - bf::path package_backup = ci::GetBackupPathForPackagePath(package_path); - bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path); - bf::path icon_backup = ci::GetBackupPathForIconFile(icon_path); - ASSERT_FALSE(bf::exists(package_backup)); - ASSERT_FALSE(bf::exists(manifest_backup)); - ASSERT_FALSE(bf::exists(icon_backup)); -} - -void ValidatePackage(const std::string& pkgid, const std::string& appid, - PackageType type) { - ASSERT_TRUE(ci::IsPackageInstalled(pkgid, ci::GetRequestMode())); - ValidatePackageFS(pkgid, appid, type); -} - -void CheckPackageNonExistance(const std::string& pkgid, - const std::string& appid) { - ASSERT_FALSE(ci::IsPackageInstalled(pkgid, ci::GetRequestMode())); - PackageCheckCleanup(pkgid, appid); -} - -std::unique_ptr CreateQueryInterface(PackageType type) { - std::unique_ptr query_interface; - switch (type) { - case PackageType::TPK: - query_interface.reset(new tpk::TpkAppQueryInterface()); - break; - case PackageType::WGT: - query_interface.reset(new wgt::WgtAppQueryInterface()); - break; - } - return query_interface; -} - -std::unique_ptr CreateInstaller(ci::PkgMgrPtr pkgmgr, - PackageType type) { - std::unique_ptr installer; - switch (type) { - case PackageType::TPK: - installer.reset(new tpk::TpkInstaller(pkgmgr)); - break; - case PackageType::WGT: - installer.reset(new wgt::WgtInstaller(pkgmgr)); - break; - } - return installer; -} - -ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr, - PackageType type, - RequestResult mode) { - std::unique_ptr installer = CreateInstaller(pkgmgr, type); - switch (mode) { - case RequestResult::FAIL: - installer->AddStep(); - break; - case RequestResult::CRASH: - installer->AddStep(); - default: - break; - } - return installer->Run(); -} - -ci::AppInstaller::Result Install(const bf::path& path, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-i", path.c_str()}; - std::unique_ptr query_interface = - CreateQueryInterface(type); - auto pkgmgr = - ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast(argv), - query_interface.get()); - if (!pkgmgr) { - LOG(ERROR) << "Failed to initialize pkgmgr interface"; - return ci::AppInstaller::Result::UNKNOWN; - } - return RunInstallerWithPkgrmgr(pkgmgr, type, mode); -} - -ci::AppInstaller::Result Update(const bf::path& path_old, - const bf::path& path_new, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - if (Install(path_old, type) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot update"; - return ci::AppInstaller::Result::UNKNOWN; - } - return Install(path_new, type, mode); -} - -ci::AppInstaller::Result Uninstall(const std::string& pkgid, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-d", pkgid.c_str()}; - std::unique_ptr query_interface = - CreateQueryInterface(type); - auto pkgmgr = - ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast(argv), - query_interface.get()); - if (!pkgmgr) { - LOG(ERROR) << "Failed to initialize pkgmgr interface"; - return ci::AppInstaller::Result::UNKNOWN; - } - return RunInstallerWithPkgrmgr(pkgmgr, type, mode); -} - -ci::AppInstaller::Result Reinstall(const bf::path& path, - const bf::path& delta_dir, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - if (Install(path, type) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform RDS"; - return ci::AppInstaller::Result::UNKNOWN; - } - const char* argv[] = {"", "-r", delta_dir.c_str()}; - std::unique_ptr query_interface = - CreateQueryInterface(type); - auto pkgmgr = - ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast(argv), - query_interface.get()); - if (!pkgmgr) { - LOG(ERROR) << "Failed to initialize pkgmgr interface"; - return ci::AppInstaller::Result::UNKNOWN; - } - return RunInstallerWithPkgrmgr(pkgmgr, type, mode); -} - -ci::AppInstaller::Result DeltaInstall(const bf::path& path, - const bf::path& delta_package, PackageType type) { - if (Install(path, type) != ci::AppInstaller::Result::OK) { - LOG(ERROR) << "Failed to install application. Cannot perform RDS"; - return ci::AppInstaller::Result::UNKNOWN; - } - return Install(delta_package, type); -} - -ci::AppInstaller::Result Recover(const bf::path& recovery_file, - PackageType type, - RequestResult mode = RequestResult::NORMAL) { - const char* argv[] = {"", "-e", recovery_file.c_str()}; - std::unique_ptr query_interface = - CreateQueryInterface(type); - auto pkgmgr = - ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast(argv), - query_interface.get()); - if (!pkgmgr) { - LOG(ERROR) << "Failed to initialize pkgmgr interface"; - return ci::AppInstaller::Result::UNKNOWN; - } - return RunInstallerWithPkgrmgr(pkgmgr, type, mode); -} - -} // namespace - -namespace common_installer { - -class SmokeEnvironment : public testing::Environment { - public: - explicit SmokeEnvironment(const bf::path& home) : home_(home) { - } - void SetUp() override { - bs::error_code error; - bf::remove_all(home_ / kApplicationDirBackup, error); - bf::remove_all(home_ / KUserAppsDirBackup, error); - if (bf::exists(home_ / KUserAppsDir)) { - bf::rename(home_ / KUserAppsDir, home_ / KUserAppsDirBackup, error); - assert(!error); - } - if (bf::exists(home_ / kApplicationDir)) { - bf::rename(home_ / kApplicationDir, home_ / kApplicationDirBackup, error); - assert(!error); - } - } - void TearDown() override { - bs::error_code error; - bf::remove_all(home_ / kApplicationDir, error); - bf::remove_all(home_ / KUserAppsDir, error); - if (bf::exists(home_ / KUserAppsDirBackup)) - bf::rename(home_ / KUserAppsDirBackup, home_ / KUserAppsDir, error); - if (bf::exists(home_ / kApplicationDirBackup)) - bf::rename(home_ / kApplicationDirBackup, home_ / kApplicationDir, error); - } - - private: - bf::path home_; -}; - -class SmokeTest : public testing::Test { -}; - -TEST_F(SmokeTest, InstallationMode) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/InstallationMode.wgt"; // NOLINT - std::string pkgid = "smokeapp03"; - std::string appid = "smokeapp03.InstallationMode"; - ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::WGT); -} - -TEST_F(SmokeTest, UpdateMode) { - bf::path path_old = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode.wgt"; // NOLINT - bf::path path_new = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode_2.wgt"; // NOLINT - std::string pkgid = "smokeapp04"; - std::string appid = "smokeapp04.UpdateMode"; - ASSERT_EQ(Update(path_old, path_new, PackageType::WGT), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::WGT); - - ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); -} - -TEST_F(SmokeTest, DeinstallationMode) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/DeinstallationMode.wgt"; // NOLINT - std::string pkgid = "smokeapp05"; - std::string appid = "smokeapp05.DeinstallationMode"; - ASSERT_EQ(Install(path, PackageType::WGT), - ci::AppInstaller::Result::OK); - ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, appid); -} - -TEST_F(SmokeTest, RDSMode) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/RDSMode.wgt"; // NOLINT - std::string delta_directory = "/usr/share/app-installers-ut/test_samples/smoke/delta_dir/"; // NOLINT - std::string pkgid = "smokeapp11"; - std::string appid = "smokeapp11.RDSMode"; - ASSERT_EQ(Reinstall(path, delta_directory, PackageType::WGT), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::WGT); - - // Check delta modifications - bf::path root_path = ci::GetRootAppPath(); - 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"); -} - -TEST_F(SmokeTest, DeltaMode) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/DeltaMode.wgt"; // NOLINT - std::string delta_package = "/usr/share/app-installers-ut/test_samples/smoke/DeltaMode.delta"; // NOLINT - std::string pkgid = "smokeapp17"; - std::string appid = "smokeapp17.DeltaMode"; - ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::WGT); - - // Check delta modifications - bf::path root_path = ci::GetRootAppPath(); - 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 - ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png")); // NOLINT - ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js")); - ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"); -} - -TEST_F(SmokeTest, DeltaMode_Tpk) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/DeltaMode_Tpk.tpk"; // NOLINT - std::string delta_package = "/usr/share/app-installers-ut/test_samples/smoke/DeltaMode_Tpk.delta"; // NOLINT - std::string pkgid = "smokeapp18"; - std::string appid = "smokeapp18.DeltaModeTpk"; - ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::TPK), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::TPK); - - // Check delta modifications - bf::path root_path = ci::GetRootAppPath(); - ASSERT_FALSE(bf::exists(root_path / pkgid / "DELETED")); - ASSERT_TRUE(bf::exists(root_path / pkgid / "ADDED")); - ASSERT_TRUE(bf::exists(root_path / pkgid / "bin" / "native")); - ASSERT_TRUE(bf::exists(root_path / pkgid / "shared" / "res" / "native.png")); - ValidateFileContentInPackage(pkgid, "MODIFIED", "version 2\n"); -} - -TEST_F(SmokeTest, RecoveryMode_ForInstallation) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_ForInstallation.wgt"; // NOLINT - ASSERT_DEATH(Install(path, PackageType::WGT, RequestResult::CRASH), ".*"); - - std::string pkgid = "smokeapp09"; - std::string appid = "smokeapp09.RecoveryModeForInstallation"; - bf::path recovery_file = FindRecoveryFile(); - ASSERT_FALSE(recovery_file.empty()); - ASSERT_EQ(Recover(recovery_file, PackageType::WGT), - ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, appid); -} - -TEST_F(SmokeTest, RecoveryMode_ForUpdate) { - bf::path path_old = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_ForUpdate.wgt"; // NOLINT - bf::path path_new = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_ForUpdate_2.wgt"; // NOLINT - RemoveAllRecoveryFiles(); - ASSERT_DEATH(Update(path_old, path_new, PackageType::WGT, - RequestResult::CRASH), ".*"); - - std::string pkgid = "smokeapp10"; - std::string appid = "smokeapp10.RecoveryModeForUpdate"; - bf::path recovery_file = FindRecoveryFile(); - ASSERT_FALSE(recovery_file.empty()); - ASSERT_EQ(Recover(recovery_file, PackageType::WGT), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::WGT); - - ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); -} - -TEST_F(SmokeTest, InstallationMode_GoodSignature) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/InstallationMode_GoodSignature.wgt"; // NOLINT - ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); -} - -TEST_F(SmokeTest, InstallationMode_WrongSignature) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/InstallationMode_WrongSignature.wgt"; // NOLINT - ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR); -} - -TEST_F(SmokeTest, InstallationMode_Rollback) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/InstallationMode_Rollback.wgt"; // NOLINT - std::string pkgid = "smokeapp06"; - std::string appid = "smokeapp06.InstallationModeRollback"; - ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL), - ci::AppInstaller::Result::ERROR); - CheckPackageNonExistance(pkgid, appid); -} - -TEST_F(SmokeTest, UpdateMode_Rollback) { - bf::path path_old = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode_Rollback.wgt"; // NOLINT - bf::path path_new = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode_Rollback_2.wgt"; // NOLINT - std::string pkgid = "smokeapp07"; - std::string appid = "smokeapp07.UpdateModeRollback"; - ASSERT_EQ(Update(path_old, path_new, PackageType::WGT, RequestResult::FAIL), - ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, appid, PackageType::WGT); - - ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n")); -} - -TEST_F(SmokeTest, DeinstallationMode_Rollback) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/DeinstallationMode_Rollback.wgt"; // NOLINT - std::string pkgid = "smokeapp08"; - std::string appid = "smokeapp08.DeinstallationModeRollback"; - ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK); - ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, RequestResult::FAIL), - ci::AppInstaller::Result::ERROR); - ValidatePackage(pkgid, appid, PackageType::WGT); -} - -TEST_F(SmokeTest, InstallationMode_Tpk) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/InstallationMode_Tpk.tpk"; // NOLINT - std::string pkgid = "smokeapp12"; - std::string appid = "smokeapp12.InstallationModeTpk"; - ASSERT_EQ(Install(path, PackageType::TPK), ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::TPK); -} - -TEST_F(SmokeTest, UpdateMode_Tpk) { - bf::path path_old = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode_Tpk.tpk"; // NOLINT - bf::path path_new = "/usr/share/app-installers-ut/test_samples/smoke/UpdateMode_Tpk_2.tpk"; // NOLINT - std::string pkgid = "smokeapp13"; - std::string appid = "smokeapp13.UpdateModeTpk"; - ASSERT_EQ(Update(path_old, path_new, PackageType::TPK), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::TPK); - - ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n")); -} - -TEST_F(SmokeTest, DeinstallationMode_Tpk) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/DeinstallationMode_Tpk.tpk"; // NOLINT - std::string pkgid = "smokeapp14"; - std::string appid = "smokeapp14.DeinstallationModeTpk"; - ASSERT_EQ(Install(path, PackageType::TPK), - ci::AppInstaller::Result::OK); - ASSERT_EQ(Uninstall(pkgid, PackageType::TPK), ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, appid); -} - -TEST_F(SmokeTest, RecoveryMode_Tpk_Installation) { - bf::path path = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_Tpk_Installation.tpk"; // NOLINT - ASSERT_DEATH(Install(path, PackageType::TPK, RequestResult::CRASH), ".*"); - - std::string pkgid = "smokeapp15"; - std::string appid = "smokeapp15.RecoveryModeTpkInstallation"; - bf::path recovery_file = FindRecoveryFile(); - ASSERT_FALSE(recovery_file.empty()); - ASSERT_EQ(Recover(recovery_file, PackageType::TPK), - ci::AppInstaller::Result::OK); - CheckPackageNonExistance(pkgid, appid); -} - -TEST_F(SmokeTest, RecoveryMode_Tpk_Update) { - bf::path path_old = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_Tpk_Update.tpk"; // NOLINT - bf::path path_new = "/usr/share/app-installers-ut/test_samples/smoke/RecoveryMode_Tpk_Update_2.tpk"; // NOLINT - RemoveAllRecoveryFiles(); - ASSERT_DEATH(Update(path_old, path_new, PackageType::TPK, - RequestResult::CRASH), ".*"); - - std::string pkgid = "smokeapp16"; - std::string appid = "smokeapp16.RecoveryModeTpkUpdate"; - bf::path recovery_file = FindRecoveryFile(); - ASSERT_FALSE(recovery_file.empty()); - ASSERT_EQ(Recover(recovery_file, PackageType::TPK), - ci::AppInstaller::Result::OK); - ValidatePackage(pkgid, appid, PackageType::TPK); - - ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "1\n")); -} - -} // namespace common_installer - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - const char* directory = getenv("HOME"); - if (!directory) { - LOG(ERROR) << "Cannot get $HOME value"; - return 1; - } - testing::AddGlobalTestEnvironment( - new common_installer::SmokeEnvironment(directory)); - return RUN_ALL_TESTS(); -} diff --git a/src/unit_tests/test_samples/smoke/DeinstallationMode.wgt b/src/unit_tests/test_samples/smoke/DeinstallationMode.wgt deleted file mode 100644 index bf5b7d09b866ae23921708bc071ffe32536cb8cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33312 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

egx4!dORJ>p=~%BDFL<-^~#hcLj4vi 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

egx4!dORJ>p=~%BDFL<-^~#hcLj4vi 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 diff --git a/src/unit_tests/test_samples/smoke/DeltaMode.wgt b/src/unit_tests/test_samples/smoke/DeltaMode.wgt deleted file mode 100644 index 283700050272e10ca310cb82d75ee1794da7dd59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34283 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

BT%}l%Zycqo% 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