From 6dc942b45ba7183acb4b7baf5ac5640f9a65db05 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Wed, 11 May 2016 10:38:55 +0200 Subject: [PATCH 01/16] Reorder steps for StepDeltaPatch StepDeltaPatch will require old_manifest_data of context structure. Steps are reordered so that in delta mode reading old configuration reading is done before applying delta package content. Change-Id: I386f54afd3ad6cb2525ee38538004f1ad767e698 --- src/hybrid/hybrid_installer.cc | 8 ++++---- src/wgt/wgt_installer.cc | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 26d5593..d49f9d3 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -185,11 +185,14 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( ci::configuration::StepParseManifest::ManifestLocation::PACKAGE, ci::configuration::StepParseManifest::StoreLocation::NORMAL); - AddStep(); AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, + ci::configuration::StepParseManifest::StoreLocation::BACKUP); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -198,9 +201,6 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); - AddStep( - ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, - ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index d56dad9..7f6b1fe 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -196,6 +196,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, false); // start file may not have changed + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, + ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep("res/wgt/"); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); @@ -208,9 +211,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); - AddStep( - ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, - ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 58143a2b61525fc4ef22ee17655acda750e21cb9 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Thu, 12 May 2016 14:51:20 +0900 Subject: [PATCH 02/16] add PROJECT_TAG as 'WGT_BACKEND' Change-Id: I2a4e6248d068229e93e97f1af55203b5dcd0f622 Signed-off-by: jongmyeongko --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7359f8..08858fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ ADD_DEFINITIONS("-Wall") ADD_DEFINITIONS("-Wextra") ADD_DEFINITIONS("-fPIE") ADD_DEFINITIONS("-fPIC") +ADD_DEFINITIONS("-DPROJECT_TAG=\"WGT_BACKEND\"") SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") INCLUDE(FindPkgConfig) -- 2.7.4 From 2b417b2dc6cf479dd471a82bcdd4f44031d7af78 Mon Sep 17 00:00:00 2001 From: Kamil Rojewski Date: Fri, 13 May 2016 13:54:34 +0200 Subject: [PATCH 03/16] encrypting resources during update Change-Id: Idb4ee5a1edd356b718200fb5660971fe80ca8392 --- src/wgt/wgt_installer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 7f6b1fe..70b4f00 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -131,6 +131,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, @@ -210,6 +211,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From f8e1fefb9a7b16890c7e685a94d56707f6c06170 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Wed, 11 May 2016 17:08:36 +0200 Subject: [PATCH 04/16] Fix step order in Delta mode for hybrid app Change-Id: I9d5c90da48231f9827fd096dbeef779c17e939da --- src/hybrid/hybrid_installer.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index d49f9d3..c2d1aa6 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -186,13 +186,13 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) ci::configuration::StepParseManifest::ManifestLocation::PACKAGE, ci::configuration::StepParseManifest::StoreLocation::NORMAL); AddStep(); - AddStep( - wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); - AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); + AddStep( + wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 630f25a59c639b025fbb87fe248f5d84c53f4968 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Mon, 16 May 2016 16:07:24 +0200 Subject: [PATCH 05/16] Fix style Change-Id: I59a00a194561d25172a96c8f60314d01a5b08936 --- src/unit_tests/manifest_test.cc | 1 - src/wgt/step/common/privileges.cc | 3 ++- src/wgt/step/pkgmgr/step_generate_xml.cc | 7 +++++-- src/wgt/step/rds/step_wgt_rds_modify.h | 4 ++-- src/wgt/step/security/step_check_wgt_ime_privilege.cc | 2 ++ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/unit_tests/manifest_test.cc b/src/unit_tests/manifest_test.cc index b72a9bd..ab26141 100644 --- a/src/unit_tests/manifest_test.cc +++ b/src/unit_tests/manifest_test.cc @@ -593,5 +593,4 @@ TEST_F(ManifestTest, CategoryElement_MultipleElements) { "http://tizen.org/category/category_1"); ASSERT_CSTR_EQ(categories[2].c_str(), "http://tizen.org/category/category_2"); - } diff --git a/src/wgt/step/common/privileges.cc b/src/wgt/step/common/privileges.cc index 5634f90..20b5cc3 100644 --- a/src/wgt/step/common/privileges.cc +++ b/src/wgt/step/common/privileges.cc @@ -1,7 +1,8 @@ // 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 "privileges.h" + +#include "wgt/step/common/privileges.h" namespace wgt { namespace common { diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 43c96ee..614009e 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -429,11 +429,14 @@ common_installer::Step::Status StepGenerateXml::process() { if (!ime_uuid.empty()) { xmlTextWriterStartElement(writer, BAD_CAST "ime"); - GListRange app_range(context_->manifest_data.get()->application); + GListRange app_range( + context_->manifest_data.get()->application); if (!app_range.Empty()) { // wgt app have ui-application as first application element. // there may be service-applications but not as first element. - xmlTextWriterWriteAttribute(writer, BAD_CAST "appid", BAD_CAST (*app_range.begin())->appid); + application_x* app = *app_range.begin(); + xmlTextWriterWriteAttribute(writer, BAD_CAST "appid", + BAD_CAST app->appid); } xmlTextWriterStartElement(writer, BAD_CAST "uuid"); diff --git a/src/wgt/step/rds/step_wgt_rds_modify.h b/src/wgt/step/rds/step_wgt_rds_modify.h index f09347d..67f9d28 100644 --- a/src/wgt/step/rds/step_wgt_rds_modify.h +++ b/src/wgt/step/rds/step_wgt_rds_modify.h @@ -33,7 +33,7 @@ class StepWgtRDSModify : public common_installer::rds::StepRDSModify { std::string GetAppPath() override; }; -} // rds -} // wgt +} // namespace rds +} // namespace wgt #endif // WGT_STEP_RDS_STEP_WGT_RDS_MODIFY_H_ diff --git a/src/wgt/step/security/step_check_wgt_ime_privilege.cc b/src/wgt/step/security/step_check_wgt_ime_privilege.cc index a791bfc..034f0cf 100644 --- a/src/wgt/step/security/step_check_wgt_ime_privilege.cc +++ b/src/wgt/step/security/step_check_wgt_ime_privilege.cc @@ -10,6 +10,8 @@ #include +#include + namespace { const char kImeCategoryName[] = "http://tizen.org/category/ime"; } -- 2.7.4 From ee1a6f46c164704f34e2503501337afc94e0e1ab Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Wed, 18 May 2016 08:02:55 +0900 Subject: [PATCH 06/16] Remove blacklist feature Related with changes in app-installers https://review.tizen.org/gerrit/69947 Signed-off-by: Junghyun Yeon Change-Id: Iaf18948497f90f2e7bf600a56118f634e4da9498 --- src/wgt/wgt_installer.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 70b4f00..e61112c 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -93,7 +92,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -123,7 +121,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -184,7 +181,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -203,7 +199,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep("res/wgt/"); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -253,7 +248,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -283,7 +277,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -317,7 +310,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); - AddStep(); AddStep(); AddStep(); AddStep(); @@ -335,7 +327,6 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); - AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 522a1012907c5215af9b69b6eda73c53034354bb Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Fri, 13 May 2016 15:00:54 +0200 Subject: [PATCH 07/16] Smoke test for mount install Change-Id: I1241198b32e7154870db3710341aa717ba381b46 --- src/unit_tests/smoke_test.cc | 66 +++++++++++++++++++++ .../test_samples/smoke/MountInstallationMode.wgt | Bin 0 -> 37645 bytes .../test_samples/smoke/MountUpdateMode.wgt | Bin 0 -> 37842 bytes .../test_samples/smoke/MountUpdateMode_2.wgt | Bin 0 -> 37846 bytes 4 files changed, 66 insertions(+) create mode 100644 src/unit_tests/test_samples/smoke/MountInstallationMode.wgt create mode 100644 src/unit_tests/test_samples/smoke/MountUpdateMode.wgt create mode 100644 src/unit_tests/test_samples/smoke/MountUpdateMode_2.wgt diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc index 5bd6d95..3ab430b 100644 --- a/src/unit_tests/smoke_test.cc +++ b/src/unit_tests/smoke_test.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,23 @@ enum class RequestResult { FAIL }; +class ScopedTzipInterface { + public: + explicit ScopedTzipInterface(const std::string& pkgid) + : pkg_path_(bf::path(ci::GetRootAppPath(false)) / pkgid), + interface_(ci::GetMountLocation(pkg_path_)) { + interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid)); + } + + ~ScopedTzipInterface() { + interface_.UnmountZip(); + } + + private: + bf::path pkg_path_; + ci::TzipInterface interface_; +}; + class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface { public: bool CreatePkgMgrInstaller(pkgmgr_installer** installer, @@ -271,6 +289,32 @@ ci::AppInstaller::Result Update(const bf::path& path_old, return Install(path_new, type, mode); } +ci::AppInstaller::Result MountInstall(const bf::path& path, + PackageType type, RequestResult mode = RequestResult::NORMAL) { + const char* argv[] = {"", "-w", path.c_str()}; + TestPkgmgrInstaller pkgmgr_installer; + std::unique_ptr query_interface = + CreateQueryInterface(); + auto pkgmgr = + ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast(argv), + &pkgmgr_installer, 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 MountUpdate(const bf::path& path_old, + const bf::path& path_new, PackageType type, + RequestResult mode = RequestResult::NORMAL) { + if (MountInstall(path_old, type) != ci::AppInstaller::Result::OK) { + LOG(ERROR) << "Failed to mount-install application. Cannot mount-update"; + return ci::AppInstaller::Result::UNKNOWN; + } + return MountInstall(path_new, type, mode); +} + ci::AppInstaller::Result Uninstall(const std::string& pkgid, PackageType type, RequestResult mode = RequestResult::NORMAL) { @@ -607,6 +651,28 @@ TEST_F(SmokeTest, DeltaMode_Hybrid) { ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"); } +TEST_F(SmokeTest, MountInstallationMode) { + bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt"; + std::string pkgid = "smokeapp28"; + std::string appid = "smokeapp28.InstallationMode"; + ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK); + ScopedTzipInterface interface(pkgid); + ValidatePackage(pkgid, {appid}); +} + +TEST_F(SmokeTest, MountUpdateMode) { + bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt"; + bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt"; + std::string pkgid = "smokeapp29"; + std::string appid = "smokeapp29.UpdateMode"; + ASSERT_EQ(MountUpdate(path_old, path_new, PackageType::WGT), + ci::AppInstaller::Result::OK); + ScopedTzipInterface interface(pkgid); + ValidatePackage(pkgid, {appid}); + + ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n")); +} + } // namespace common_installer int main(int argc, char** argv) { diff --git a/src/unit_tests/test_samples/smoke/MountInstallationMode.wgt b/src/unit_tests/test_samples/smoke/MountInstallationMode.wgt new file mode 100644 index 0000000000000000000000000000000000000000..ba9d1ea66cbb39e6afd55a9c133df1057918dbd7 GIT binary patch literal 37645 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
OkTkhk{Z4Xdw`vbfupnWK8`()4e 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 literal 0 HcmV?d00001 diff --git a/src/unit_tests/test_samples/smoke/MountUpdateMode.wgt b/src/unit_tests/test_samples/smoke/MountUpdateMode.wgt new file mode 100644 index 0000000000000000000000000000000000000000..872ae62c20a9586343e64b0ca5c14af33d89c0cb GIT binary patch literal 37842 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 T^wQBzK#5<}_ztK_zP$QBzqDP| literal 0 HcmV?d00001 diff --git a/src/unit_tests/test_samples/smoke/MountUpdateMode_2.wgt b/src/unit_tests/test_samples/smoke/MountUpdateMode_2.wgt new file mode 100644 index 0000000000000000000000000000000000000000..ee5df918716dd23f97ca8c341430d15f4ba2e8eb GIT binary patch literal 37846 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 Um-5`zP68y33&ajUW}L774-zMP;Q#;t literal 0 HcmV?d00001 -- 2.7.4 From 82cbc1e3df10c4eb2b8c54372354694ed1210457 Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Tue, 24 May 2016 13:48:33 +0200 Subject: [PATCH 08/16] Fix manifest attributes This patch repairs manifest.xml attributes when ime is the type of the app. Change-Id: I6cf77401058b922e426311b5a00ad8ab48a0e64a --- src/wgt/step/configuration/step_parse.cc | 23 ++++++++++++++++++++--- src/wgt/step/pkgmgr/step_generate_xml.cc | 10 ++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index 680ab35..c438598 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -51,6 +51,7 @@ const char kCategoryWatchClock[] = "com.samsung.wmanager.WATCH_CLOCK"; const std::string kManifestVersion = "1.0.0"; const char kTizenPackageXmlNamespace[] = "http://tizen.org/ns/packages"; +const char kImeCategoryName[] = "http://tizen.org/category/ime"; const char kResWgt[] = "res/wgt"; @@ -80,7 +81,6 @@ void SetApplicationXDefaults(application_x* application) { application->screenreader = strdup("use-system-setting"); application->submode = strdup("false"); application->support_disable = strdup("false"); - application->taskmanage = strdup("true"); application->ui_gadget = strdup("false"); } @@ -252,6 +252,7 @@ bool StepParse::FillMainApplicationInfo(manifest_x* manifest) { return false; } bool has_watch_catergory = false; + bool has_ime = false; std::shared_ptr category_info = std::static_pointer_cast( parser_->GetManifestData(app_keys::kTizenCategoryKey)); @@ -262,6 +263,10 @@ bool StepParse::FillMainApplicationInfo(manifest_x* manifest) { return category == kCategoryWearableClock || category == kCategoryWatchClock; }) != category_info->categories.end(); + has_ime = std::find(category_info->categories.begin(), + category_info->categories.end(), + kImeCategoryName + ) != category_info->categories.end(); } // application data @@ -270,9 +275,10 @@ bool StepParse::FillMainApplicationInfo(manifest_x* manifest) { application->component_type = has_watch_catergory ? strdup("watchapp") : strdup("uiapp"); application->mainapp = strdup("true"); - application->nodisplay = strdup("false"); application->multiple = strdup("false"); application->appid = strdup(app_info->id().c_str()); + application->nodisplay = has_ime ? strdup("true") : strdup("false"); + application->taskmanage = has_ime ? strdup("false") : strdup("true"); SetApplicationXDefaults(application); if (has_watch_catergory) application->ambient_support = @@ -309,12 +315,21 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { parser_->GetManifestData(app_keys::kTizenServiceKey)); if (!service_list) return true; + bool has_ime = false; + std::shared_ptr category_info = + std::static_pointer_cast( + parser_->GetManifestData(app_keys::kTizenCategoryKey)); + if (category_info) { + has_ime = std::find(category_info->categories.begin(), + category_info->categories.end(), + kImeCategoryName + ) != category_info->categories.end(); + } for (auto& service_info : service_list->services) { application_x* application = reinterpret_cast (calloc(1, sizeof(application_x))); application->component_type = strdup("svcapp"); application->mainapp = strdup("false"); - application->nodisplay = strdup("false"); application->multiple = strdup("false"); application->appid = strdup(service_info.id().c_str()); application->exec = @@ -325,6 +340,8 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { service_info.on_boot() ? strdup("true") : strdup("false"); application->autorestart = service_info.auto_restart() ? strdup("true") : strdup("false"); + application->nodisplay = has_ime ? strdup("true") : strdup("false"); + application->taskmanage = has_ime ? strdup("false") : strdup("true"); SetApplicationXDefaults(application); application->ambient_support = strdup("false"); application->package = strdup(manifest->package); diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 614009e..79339f1 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -31,8 +31,9 @@ namespace { void WriteUIApplicationAttributes( xmlTextWriterPtr writer, application_x *app) { - xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage", - BAD_CAST "true"); + if (app->taskmanage) + xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage", + BAD_CAST app->taskmanage); if (app->nodisplay) xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay", BAD_CAST app->nodisplay); @@ -74,8 +75,9 @@ void WriteServiceApplicationAttributes( BAD_CAST(app->autorestart ? app->autorestart : "false")); xmlTextWriterWriteAttribute(writer, BAD_CAST "on-boot", BAD_CAST(app->onboot ? app->onboot : "false")); - xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage", - BAD_CAST "false"); + if (app->taskmanage) + xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage", + BAD_CAST app->taskmanage); } void WriteWidgetApplicationAttributes( -- 2.7.4 From 1bd5cf1b550d00f2b90dd1a187d1b1de921d5b16 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Tue, 24 May 2016 11:18:41 +0200 Subject: [PATCH 09/16] Generate widget element in platform manifest To verify, install widget with appwidget and: - check information generated in manifest file, - check creation of symlink for widgets in bin/ directory, - check preview icons in shared/res/ directory. Requires: - https://review.tizen.org/gerrit/71235 Change-Id: I2a38aaee729c4c1f18200d2f63764c4c87e7d730 --- src/hybrid/hybrid_installer.cc | 6 ++ src/wgt/CMakeLists.txt | 1 + src/wgt/step/configuration/step_parse.cc | 15 ++++- src/wgt/step/configuration/step_parse.h | 1 + src/wgt/step/filesystem/step_copy_preview_icons.cc | 52 +++++++++++++++ src/wgt/step/filesystem/step_copy_preview_icons.h | 35 ++++++++++ .../step/filesystem/step_create_symbolic_link.cc | 42 ++++++++++-- .../step/filesystem/step_create_symbolic_link.h | 4 ++ src/wgt/step/pkgmgr/step_generate_xml.cc | 75 ++++++++++++++++++++++ src/wgt/wgt_backend_data.h | 3 + src/wgt/wgt_installer.cc | 6 ++ 11 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 src/wgt/step/filesystem/step_copy_preview_icons.cc create mode 100644 src/wgt/step/filesystem/step_copy_preview_icons.h diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index c2d1aa6..dd56988 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -63,6 +63,7 @@ #include "wgt/step/configuration/step_parse.h" #include "wgt/step/configuration/step_parse_recovery.h" #include "wgt/step/encryption/step_remove_encryption_data.h" +#include "wgt/step/filesystem/step_copy_preview_icons.h" #include "wgt/step/filesystem/step_create_symbolic_link.h" #include "wgt/step/filesystem/step_wgt_patch_icons.h" #include "wgt/step/filesystem/step_wgt_patch_storage_directories.h" @@ -104,6 +105,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -146,6 +148,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -209,6 +212,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -264,6 +268,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -307,6 +312,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index 1542e28..c160de9 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -5,6 +5,7 @@ SET(SRCS step/configuration/step_parse_recovery.cc step/encryption/step_encrypt_resources.cc step/encryption/step_remove_encryption_data.cc + step/filesystem/step_copy_preview_icons.cc step/filesystem/step_create_symbolic_link.cc step/filesystem/step_wgt_patch_icons.cc step/filesystem/step_wgt_patch_storage_directories.cc diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index c438598..0b9f251 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -468,6 +468,19 @@ bool StepParse::FillMetadata(manifest_x* manifest) { return true; } +bool StepParse::FillAppWidget() { + WgtBackendData* backend_data = + static_cast(context_->backend_data.get()); + + std::shared_ptr appwidget_info = + std::static_pointer_cast( + parser_->GetManifestData( + wgt::application_widget_keys::kTizenAppWidgetFullKey)); + if (appwidget_info) + backend_data->appwidgets.set(*appwidget_info); + return true; +} + bool StepParse::FillAccounts(manifest_x* manifest) { std::shared_ptr account_info = std::static_pointer_cast( @@ -507,7 +520,7 @@ bool StepParse::FillImeInfo() { } bool StepParse::FillExtraManifestInfo(manifest_x* manifest) { - return FillAccounts(manifest) && FillImeInfo(); + return FillAccounts(manifest) && FillImeInfo() && FillAppWidget(); } bool StepParse::FillManifestX(manifest_x* manifest) { diff --git a/src/wgt/step/configuration/step_parse.h b/src/wgt/step/configuration/step_parse.h index 9bc1b73..4a41978 100644 --- a/src/wgt/step/configuration/step_parse.h +++ b/src/wgt/step/configuration/step_parse.h @@ -66,6 +66,7 @@ class StepParse : public common_installer::Step { bool FillExtraManifestInfo(manifest_x* manifest); bool FillAccounts(manifest_x* manifest); bool FillImeInfo(); + bool FillAppWidget(); bool FillBackgroundCategoryInfo(manifest_x* manifest); bool FillManifestX(manifest_x* manifest); diff --git a/src/wgt/step/filesystem/step_copy_preview_icons.cc b/src/wgt/step/filesystem/step_copy_preview_icons.cc new file mode 100644 index 0000000..88fc004 --- /dev/null +++ b/src/wgt/step/filesystem/step_copy_preview_icons.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2016 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/filesystem/step_copy_preview_icons.h" + +#include +#include + +#include + +#include "wgt/wgt_backend_data.h" + +namespace bf = boost::filesystem; +namespace ci = common_installer; + +namespace { + +const char kResWgt[] = "res/wgt"; +const char kSharedRes[] = "shared/res"; + +} // namespace + +namespace wgt { +namespace filesystem { + +ci::Step::Status StepCopyPreviewIcons::process() { + WgtBackendData* backend_data = + static_cast(context_->backend_data.get()); + for (auto& appwidget : backend_data->appwidgets.get().app_widgets()) { + for (auto& size : appwidget.content_size) { + if (!size.preview.empty()) { + bf::path icon_path = + context_->pkg_path.get() / kResWgt / size.preview; + std::string type = wgt::parse::AppWidgetSizeTypeToString(size.type); + std::string icon_name = appwidget.id + "." + type + "." + "preview" + + bf::path(size.preview).extension().string(); + bf::path preview_icon = + context_->pkg_path.get() / kSharedRes / icon_name; + if (!ci::CopyFile(icon_path, preview_icon)) { + LOG(ERROR) << "Cannot create preview icon: " << preview_icon; + return Status::ICON_ERROR; + } + } + } + } + LOG(DEBUG) << "Preview icons created"; + return Status::OK; +} + +} // namespace filesystem +} // namespace wgt diff --git a/src/wgt/step/filesystem/step_copy_preview_icons.h b/src/wgt/step/filesystem/step_copy_preview_icons.h new file mode 100644 index 0000000..ee9c525 --- /dev/null +++ b/src/wgt/step/filesystem/step_copy_preview_icons.h @@ -0,0 +1,35 @@ +// Copyright (c) 2016 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_FILESYSTEM_STEP_COPY_PREVIEW_ICONS_H_ +#define WGT_STEP_FILESYSTEM_STEP_COPY_PREVIEW_ICONS_H_ + +#include + +#include +#include +#include + +namespace wgt { +namespace filesystem { + +/** + * \brief Step that create copy of preview icons in shared/res/ directory + */ +class StepCopyPreviewIcons : public common_installer::Step { + public: + using Step::Step; + + Status process() override; + Status clean() override { return Status::OK; } + Status undo() override { return Status::OK; } + Status precheck() override { return Status::OK; } + + SCOPE_LOG_TAG(CopyPreviewIcons) +}; + +} // namespace filesystem +} // namespace wgt + +#endif // WGT_STEP_FILESYSTEM_STEP_COPY_PREVIEW_ICONS_H_ diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.cc b/src/wgt/step/filesystem/step_create_symbolic_link.cc index 397c7d8..b23fcae 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.cc +++ b/src/wgt/step/filesystem/step_create_symbolic_link.cc @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,20 +17,22 @@ #include #include +#include "wgt/wgt_backend_data.h" + +namespace bf = boost::filesystem; +namespace bs = boost::system; namespace { const char kWrtServiceBinaryPath[] = "/usr/bin/wrt-service"; +const char kWidgetClientBinaryPath[] = "/usr/bin/widget-client"; } // namespace namespace wgt { namespace filesystem { -namespace bf = boost::filesystem; - -common_installer::Step::Status StepCreateSymbolicLink::process() { - assert(context_->manifest_data.get()); +bool StepCreateSymbolicLink::CreateSymlinksForApps() { boost::system::error_code error; for (application_x* app : GListRange(context_->manifest_data.get()->application)) { @@ -52,11 +55,38 @@ common_installer::Step::Status StepCreateSymbolicLink::process() { if (error) { LOG(ERROR) << "Failed to set symbolic link " << boost::system::system_error(error).what(); - return Step::Status::ERROR; + return false; } } - LOG(DEBUG) << "Symlinks created successfully"; + return true; +} +bool StepCreateSymbolicLink::CreateSymlinksForAppWidgets() { + WgtBackendData* backend_data = + static_cast(context_->backend_data.get()); + for (auto& appwidget : backend_data->appwidgets.get().app_widgets()) { + bf::path exec_path = context_->pkg_path.get() / "bin" / appwidget.id; + bs::error_code error; + bf::create_symlink(kWidgetClientBinaryPath, exec_path, error); + if (error) { + LOG(ERROR) << "Failed to create symlink for app widget: " + << appwidget.id; + return false; + } + } + return true; +} + +common_installer::Step::Status StepCreateSymbolicLink::process() { + assert(context_->manifest_data.get()); + + if (!CreateSymlinksForApps()) + return Status::APP_DIR_ERROR; + + if (!CreateSymlinksForAppWidgets()) + return Status::APP_DIR_ERROR; + + LOG(DEBUG) << "Symlinks created successfully"; return Status::OK; } diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.h b/src/wgt/step/filesystem/step_create_symbolic_link.h index 0efa491..dbe650b 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.h +++ b/src/wgt/step/filesystem/step_create_symbolic_link.h @@ -52,6 +52,10 @@ class StepCreateSymbolicLink : public common_installer::Step { */ Status precheck() override { return Status::OK; } + private: + bool CreateSymlinksForApps(); + bool CreateSymlinksForAppWidgets(); + SCOPE_LOG_TAG(SymbolicLink) }; diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 79339f1..bfcfb23 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -23,12 +23,16 @@ #include #include "wgt/step/common/privileges.h" +#include "wgt/wgt_backend_data.h" namespace bs = boost::system; namespace bf = boost::filesystem; namespace { +const char kResWgt[] = "res/wgt"; +const char kSharedRes[] = "shared/res"; + void WriteUIApplicationAttributes( xmlTextWriterPtr writer, application_x *app) { if (app->taskmanage) @@ -499,6 +503,77 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterEndElement(writer); } + WgtBackendData* backend_data = + static_cast(context_->backend_data.get()); + bf::path widget_content_path = context_->pkg_path.get() / kResWgt; + for (auto& appwidget : backend_data->appwidgets.get().app_widgets()) { + xmlTextWriterStartElement(writer, BAD_CAST "widget"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "appid", + BAD_CAST appwidget.id.c_str()); + xmlTextWriterWriteAttribute(writer, BAD_CAST "primary", + BAD_CAST (appwidget.primary ? "true" : "false")); // NOLINT + xmlTextWriterWriteAttribute(writer, BAD_CAST "abi", + BAD_CAST "html"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "network", + BAD_CAST "true"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay", + BAD_CAST "false"); + + if (!appwidget.label.default_value.empty()) { + xmlTextWriterStartElement(writer, BAD_CAST "label"); + xmlTextWriterWriteString(writer, + BAD_CAST appwidget.label.default_value.c_str()); + xmlTextWriterEndElement(writer); + } + for (auto& pair : appwidget.label.lang_value_map) { + xmlTextWriterStartElement(writer, BAD_CAST "label"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", + BAD_CAST pair.first.c_str()); + xmlTextWriterWriteString(writer, BAD_CAST pair.second.c_str()); + xmlTextWriterEndElement(writer); + } + + if (!appwidget.icon_src.empty()) { + xmlTextWriterStartElement(writer, BAD_CAST "icon"); + xmlTextWriterWriteString(writer, BAD_CAST appwidget.icon_src.c_str()); + xmlTextWriterEndElement(writer); + } + + xmlTextWriterStartElement(writer, BAD_CAST "box"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST "buffer"); + xmlTextWriterWriteAttribute(writer, BAD_CAST "mouse_event", + BAD_CAST (appwidget.content_mouse_event ? "true" : "false")); // NOLINT + xmlTextWriterWriteAttribute(writer, BAD_CAST "touch_effect", + BAD_CAST (appwidget.content_touch_effect ? "true" : "false")); // NOLINT + xmlTextWriterStartElement(writer, BAD_CAST "script"); + bf::path src = widget_content_path / appwidget.content_src; + xmlTextWriterWriteAttribute(writer, BAD_CAST "src", + BAD_CAST src.c_str()); + xmlTextWriterEndElement(writer); + for (auto& size : appwidget.content_size) { + xmlTextWriterStartElement(writer, BAD_CAST "size"); + + std::string type = wgt::parse::AppWidgetSizeTypeToString(size.type); + if (!size.preview.empty()) { + std::string icon_name = appwidget.id + "." + type + "." + "preview" + + bf::path(size.preview).extension().string(); + bf::path preview_icon = + context_->pkg_path.get() / kSharedRes / icon_name; + xmlTextWriterWriteAttribute(writer, BAD_CAST "preview", + BAD_CAST preview_icon.c_str()); // NOLINT + } + + xmlTextWriterWriteAttribute(writer, BAD_CAST "need_frame", + BAD_CAST "true"); + xmlTextWriterWriteString(writer, + BAD_CAST type.c_str()); + xmlTextWriterEndElement(writer); + } + xmlTextWriterEndElement(writer); + + xmlTextWriterEndElement(writer); + } + xmlTextWriterEndElement(writer); xmlTextWriterEndDocument(writer); diff --git a/src/wgt/wgt_backend_data.h b/src/wgt/wgt_backend_data.h index 8fdf4a4..3d2791d 100644 --- a/src/wgt/wgt_backend_data.h +++ b/src/wgt/wgt_backend_data.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -25,6 +26,8 @@ class WgtBackendData : public common_installer::BackendData { * \brief Property of SettingInfo */ Property settings; + + Property appwidgets; }; } // namespace wgt diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index e61112c..ffb2d59 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -62,6 +62,7 @@ #include "wgt/step/configuration/step_parse_recovery.h" #include "wgt/step/encryption/step_encrypt_resources.h" #include "wgt/step/encryption/step_remove_encryption_data.h" +#include "wgt/step/filesystem/step_copy_preview_icons.h" #include "wgt/step/filesystem/step_create_symbolic_link.h" #include "wgt/step/filesystem/step_wgt_patch_icons.h" #include "wgt/step/filesystem/step_wgt_patch_storage_directories.h" @@ -108,6 +109,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep( @@ -144,6 +146,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -217,6 +220,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -264,6 +268,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep( @@ -299,6 +304,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep( -- 2.7.4 From 81aab64a91bfea63f6f3076fec774c747734ccf5 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Wed, 9 Mar 2016 17:18:58 +0100 Subject: [PATCH 10/16] External installation This patch implements installation of package in external sd card storage. Tpk and wgt applications may declare preference of being installed on external storage. If so and space requirement is satisified then their resource directory is installed in sd card with use of app2sd API. Following patchsets should be submitted together: - https://review.tizen.org/gerrit/61678 - https://review.tizen.org/gerrit/61679 - https://review.tizen.org/gerrit/61680 Verify by: - running smoke tests, - running installation, update, deinstallation for package that prefers external installation (SD card must be inserted). Requires: - https://review.tizen.org/gerrit/#/c/64796/ Change-Id: I174c14ddfb48dc2bc1a5935c3b4799abd7f26332 --- src/hybrid/hybrid_backend_data.h | 2 +- src/hybrid/hybrid_installer.cc | 14 ++++++++++---- src/wgt/CMakeLists.txt | 1 - src/wgt/wgt_installer.cc | 16 ++++++++++++++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/hybrid/hybrid_backend_data.h b/src/hybrid/hybrid_backend_data.h index 7815a12..9cc98c9 100644 --- a/src/hybrid/hybrid_backend_data.h +++ b/src/hybrid/hybrid_backend_data.h @@ -19,7 +19,7 @@ namespace hybrid { class HybridBackendData : public wgt::WgtBackendData { public: - HybridBackendData() { } + HybridBackendData() : tpk_manifest_data(nullptr) { } ~HybridBackendData() override { if (tpk_manifest_data.get()) pkgmgr_parser_free_manifest_xml(tpk_manifest_data.get()); diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index dd56988..6dc43ca 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +63,6 @@ #include "hybrid/step/configuration/step_stash_tpk_config.h" #include "hybrid/step/encryption/step_encrypt_resources.h" #include "wgt/step/configuration/step_parse.h" -#include "wgt/step/configuration/step_parse_recovery.h" #include "wgt/step/encryption/step_remove_encryption_data.h" #include "wgt/step/filesystem/step_copy_preview_icons.h" #include "wgt/step/filesystem/step_create_symbolic_link.h" @@ -100,6 +101,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -142,6 +144,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -168,6 +171,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( ci::Plugin::ActionType::Uninstall); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -208,6 +212,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -229,19 +234,20 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( ci::configuration::StepParseManifest::ManifestLocation::RECOVERY, ci::configuration::StepParseManifest::StoreLocation::NORMAL); - AddStep(); - AddStep(); - AddStep(); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); break; case ci::RequestType::Clear: AddStep(pkgmgr_); + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, + ci::configuration::StepParseManifest::StoreLocation::NORMAL); AddStep(); break; case ci::RequestType::MountInstall: diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index c160de9..0b4c6d9 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -2,7 +2,6 @@ SET(SRCS step/common/privileges.cc step/configuration/step_parse.cc - step/configuration/step_parse_recovery.cc step/encryption/step_encrypt_resources.cc step/encryption/step_remove_encryption_data.cc step/filesystem/step_copy_preview_icons.cc diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index ffb2d59..f15ccf5 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +61,6 @@ #include #include "wgt/step/configuration/step_parse.h" -#include "wgt/step/configuration/step_parse_recovery.h" #include "wgt/step/encryption/step_encrypt_resources.h" #include "wgt/step/encryption/step_remove_encryption_data.h" #include "wgt/step/filesystem/step_copy_preview_icons.h" @@ -102,6 +103,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -139,6 +141,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -162,6 +165,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::NORMAL); AddStep(); + AddStep(); AddStep( ci::Plugin::ActionType::Uninstall); AddStep(); @@ -184,6 +188,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -215,6 +220,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -232,11 +238,14 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) case ci::RequestType::Recovery: { AddStep(pkgmgr_); AddStep(); - AddStep(); + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::RECOVERY, + ci::configuration::StepParseManifest::StoreLocation::NORMAL); AddStep(); AddStep(); AddStep(); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -244,6 +253,9 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) } case ci::RequestType::Clear: { AddStep(pkgmgr_); + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, + ci::configuration::StepParseManifest::StoreLocation::NORMAL); AddStep(); break; } -- 2.7.4 From 637f93b378c29f5fd0b4d6ed99c8756cc390ffa2 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 26 May 2016 17:14:35 +0900 Subject: [PATCH 11/16] Add StepCheckTizenVersion Change-Id: Ic006f0e6f5bf7c99c30aa5eb1c1c4866c294f867 Signed-off-by: Sangyoon Jang --- src/hybrid/hybrid_installer.cc | 8 ++++++++ src/wgt/wgt_installer.cc | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index 6dc43ca..c1765cc 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -129,6 +131,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -200,6 +203,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -260,6 +264,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -296,6 +301,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -337,6 +343,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -359,6 +366,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index f15ccf5..13176b2 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -125,6 +127,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -183,6 +186,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, false); + AddStep(); AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, @@ -204,6 +208,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, ci::configuration::StepParseManifest::StoreLocation::BACKUP); + AddStep(); AddStep("res/wgt/"); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); @@ -264,6 +269,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -294,6 +300,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -328,6 +335,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -345,6 +353,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::INSTALLED, true); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From bf6e12d270b56e807c01648029e1b089dca51539 Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Tue, 31 May 2016 12:46:10 +0200 Subject: [PATCH 12/16] Privilages refactor This patch moves the privileges.h header from wgt-backend to app-installer repository. It collects the privileges definitions to one place. The following patchsets should be submitted together: - https://review.tizen.org/gerrit/72341 - https://review.tizen.org/gerrit/72342 Change-Id: Ia714e68aafd32117bb5eeafe0a51094244425b8d --- src/wgt/CMakeLists.txt | 1 - src/wgt/step/common/privileges.cc | 13 ------------- src/wgt/step/common/privileges.h | 16 ---------------- src/wgt/step/pkgmgr/step_generate_xml.cc | 2 +- src/wgt/step/security/step_add_default_privileges.cc | 11 +++-------- src/wgt/step/security/step_check_wgt_ime_privilege.cc | 2 +- 6 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 src/wgt/step/common/privileges.cc delete mode 100644 src/wgt/step/common/privileges.h diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index 0b4c6d9..ea51011 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -1,6 +1,5 @@ # Target - sources SET(SRCS - step/common/privileges.cc step/configuration/step_parse.cc step/encryption/step_encrypt_resources.cc step/encryption/step_remove_encryption_data.cc diff --git a/src/wgt/step/common/privileges.cc b/src/wgt/step/common/privileges.cc deleted file mode 100644 index 20b5cc3..0000000 --- a/src/wgt/step/common/privileges.cc +++ /dev/null @@ -1,13 +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/common/privileges.h" - -namespace wgt { -namespace common { -namespace privileges { -const char kImePrivilegeName[] = "http://tizen.org/privilege/ime"; -} // namespace privileges -} // namespace common -} // namespace wgt diff --git a/src/wgt/step/common/privileges.h b/src/wgt/step/common/privileges.h deleted file mode 100644 index 5a36ba6..0000000 --- a/src/wgt/step/common/privileges.h +++ /dev/null @@ -1,16 +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_COMMON_PRIVILEGES_H_ -#define WGT_STEP_COMMON_PRIVILEGES_H_ - -namespace wgt { -namespace common { -namespace privileges { -extern const char kImePrivilegeName[]; -} // namespace privileges -} // namespace common -} // namespace wgt - -#endif // WGT_STEP_COMMON_PRIVILEGES_H_ diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index bfcfb23..6bf7403 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -22,7 +23,6 @@ #include #include -#include "wgt/step/common/privileges.h" #include "wgt/wgt_backend_data.h" namespace bs = boost::system; diff --git a/src/wgt/step/security/step_add_default_privileges.cc b/src/wgt/step/security/step_add_default_privileges.cc index 3cbbe1f..e5e0288 100644 --- a/src/wgt/step/security/step_add_default_privileges.cc +++ b/src/wgt/step/security/step_add_default_privileges.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "wgt/step/security/step_add_default_privileges.h" +#include #include @@ -10,13 +11,6 @@ #include #include -namespace { - -const char kPrivForWebApp[] = - "http://tizen.org/privilege/internal/webappdefault"; - -} // namespace - namespace wgt { namespace security { @@ -30,7 +24,8 @@ common_installer::Step::Status StepAddDefaultPrivileges::precheck() { common_installer::Step::Status StepAddDefaultPrivileges::process() { manifest_x* m = context_->manifest_data.get(); - m->privileges = g_list_append(m->privileges, strdup(kPrivForWebApp)); + m->privileges = g_list_append(m->privileges, + strdup(common::privileges::kPrivForWebApp)); return Status::OK; } diff --git a/src/wgt/step/security/step_check_wgt_ime_privilege.cc b/src/wgt/step/security/step_check_wgt_ime_privilege.cc index 034f0cf..9976852 100644 --- a/src/wgt/step/security/step_check_wgt_ime_privilege.cc +++ b/src/wgt/step/security/step_check_wgt_ime_privilege.cc @@ -3,12 +3,12 @@ // found in the LICENSE file. #include -#include #include #include #include +#include #include -- 2.7.4 From e5477100569cdc671f62974f69db802f041a0c0c Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Wed, 1 Jun 2016 12:56:52 +0200 Subject: [PATCH 13/16] Remove ime checking for tizen:service Ime app is supposed to be main app only. This is not related to tizen:service (service application). Change-Id: I4c0046a07c4d019887a084d3cbe64127e89d6886 --- src/wgt/step/configuration/step_parse.cc | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index 0b9f251..ad485ca 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -265,8 +265,8 @@ bool StepParse::FillMainApplicationInfo(manifest_x* manifest) { }) != category_info->categories.end(); has_ime = std::find(category_info->categories.begin(), category_info->categories.end(), - kImeCategoryName - ) != category_info->categories.end(); + kImeCategoryName) + != category_info->categories.end(); } // application data @@ -315,16 +315,6 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { parser_->GetManifestData(app_keys::kTizenServiceKey)); if (!service_list) return true; - bool has_ime = false; - std::shared_ptr category_info = - std::static_pointer_cast( - parser_->GetManifestData(app_keys::kTizenCategoryKey)); - if (category_info) { - has_ime = std::find(category_info->categories.begin(), - category_info->categories.end(), - kImeCategoryName - ) != category_info->categories.end(); - } for (auto& service_info : service_list->services) { application_x* application = reinterpret_cast (calloc(1, sizeof(application_x))); @@ -340,8 +330,8 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { service_info.on_boot() ? strdup("true") : strdup("false"); application->autorestart = service_info.auto_restart() ? strdup("true") : strdup("false"); - application->nodisplay = has_ime ? strdup("true") : strdup("false"); - application->taskmanage = has_ime ? strdup("false") : strdup("true"); + application->nodisplay = strdup("false"); + application->taskmanage = strdup("true"); SetApplicationXDefaults(application); application->ambient_support = strdup("false"); application->package = strdup(manifest->package); -- 2.7.4 From 49b41267bd5f173571993f006cb60f1bf6a60851 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Thu, 2 Jun 2016 14:58:32 +0200 Subject: [PATCH 14/16] STEP_NAME marco Adding marco to print name of step that failed in AppInstaller class Following must be submitted together: - https://review.tizen.org/gerrit/72827 - https://review.tizen.org/gerrit/72828 - https://review.tizen.org/gerrit/72829 Change-Id: I88056f428cc88ceb1a0c375103f4acc410314abe --- src/hybrid/step/configuration/step_merge_tpk_config.h | 2 +- src/hybrid/step/configuration/step_stash_tpk_config.h | 2 +- src/hybrid/step/encryption/step_encrypt_resources.h | 2 +- src/unit_tests/smoke_test_helper.cc | 2 ++ src/wgt/step/configuration/step_parse.h | 2 +- src/wgt/step/configuration/step_parse_recovery.h | 2 +- src/wgt/step/encryption/step_encrypt_resources.h | 2 +- src/wgt/step/encryption/step_remove_encryption_data.h | 2 +- src/wgt/step/filesystem/step_copy_preview_icons.h | 2 +- src/wgt/step/filesystem/step_create_symbolic_link.h | 2 +- src/wgt/step/filesystem/step_wgt_patch_icons.h | 2 +- src/wgt/step/filesystem/step_wgt_patch_storage_directories.h | 2 +- src/wgt/step/filesystem/step_wgt_prepare_package_directory.h | 2 +- src/wgt/step/filesystem/step_wgt_resource_directory.h | 2 +- src/wgt/step/filesystem/step_wgt_update_package_directory.h | 2 +- src/wgt/step/pkgmgr/step_generate_xml.h | 2 +- src/wgt/step/rds/step_wgt_rds_modify.h | 2 ++ src/wgt/step/security/step_add_default_privileges.h | 2 +- src/wgt/step/security/step_check_settings_level.h | 2 +- src/wgt/step/security/step_check_wgt_ime_privilege.h | 2 +- src/wgt/step/security/step_check_wgt_notification_category.h | 2 ++ src/wgt/step/security/step_direct_manifest_check_signature.h | 2 +- 22 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/hybrid/step/configuration/step_merge_tpk_config.h b/src/hybrid/step/configuration/step_merge_tpk_config.h index 0414abe..2171d59 100644 --- a/src/hybrid/step/configuration/step_merge_tpk_config.h +++ b/src/hybrid/step/configuration/step_merge_tpk_config.h @@ -25,7 +25,7 @@ class StepMergeTpkConfig : public common_installer::Step { Status undo() override { return Status::OK; } Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(MergeTpkConfig) + STEP_NAME(MergeTpkConfig) }; } // namespace configuration diff --git a/src/hybrid/step/configuration/step_stash_tpk_config.h b/src/hybrid/step/configuration/step_stash_tpk_config.h index 7cc889c..2ac4716 100644 --- a/src/hybrid/step/configuration/step_stash_tpk_config.h +++ b/src/hybrid/step/configuration/step_stash_tpk_config.h @@ -25,7 +25,7 @@ class StepStashTpkConfig : public common_installer::Step { Status undo() override { return Status::OK; } Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(StashTpkConfig) + STEP_NAME(StashTpkConfig) }; } // namespace configuration diff --git a/src/hybrid/step/encryption/step_encrypt_resources.h b/src/hybrid/step/encryption/step_encrypt_resources.h index ec66852..88b0f5b 100644 --- a/src/hybrid/step/encryption/step_encrypt_resources.h +++ b/src/hybrid/step/encryption/step_encrypt_resources.h @@ -24,7 +24,7 @@ class StepEncryptResources : public wgt::encryption::StepEncryptResources { private: void SetEncryptionRoot() override; - SCOPE_LOG_TAG(EncryptResources) + STEP_NAME(EncryptResources) }; } // namespace encryption diff --git a/src/unit_tests/smoke_test_helper.cc b/src/unit_tests/smoke_test_helper.cc index c3988d6..0d37d1c 100644 --- a/src/unit_tests/smoke_test_helper.cc +++ b/src/unit_tests/smoke_test_helper.cc @@ -23,6 +23,8 @@ class StepCrash : public ci::Step { 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; } + + STEP_NAME(Crash) }; } // namespace diff --git a/src/wgt/step/configuration/step_parse.h b/src/wgt/step/configuration/step_parse.h index 4a41978..eb7e7fa 100644 --- a/src/wgt/step/configuration/step_parse.h +++ b/src/wgt/step/configuration/step_parse.h @@ -74,7 +74,7 @@ class StepParse : public common_installer::Step { ConfigLocation config_location_; bool check_start_file_; - SCOPE_LOG_TAG(Parse) + STEP_NAME(Parse) }; } // namespace configuration diff --git a/src/wgt/step/configuration/step_parse_recovery.h b/src/wgt/step/configuration/step_parse_recovery.h index bc30019..5af4ce3 100644 --- a/src/wgt/step/configuration/step_parse_recovery.h +++ b/src/wgt/step/configuration/step_parse_recovery.h @@ -47,7 +47,7 @@ class StepParseRecovery : public StepParse { */ Status precheck() override; - SCOPE_LOG_TAG(ParseRecovery) + STEP_NAME(ParseRecovery) }; } // namespace configuration diff --git a/src/wgt/step/encryption/step_encrypt_resources.h b/src/wgt/step/encryption/step_encrypt_resources.h index 628b0e9..27e4d02 100644 --- a/src/wgt/step/encryption/step_encrypt_resources.h +++ b/src/wgt/step/encryption/step_encrypt_resources.h @@ -63,7 +63,7 @@ class StepEncryptResources : public common_installer::Step { bool EncryptFile(const boost::filesystem::path &src); bool ToBeEncrypted(const boost::filesystem::path &file); WgtBackendData* backend_data_; - SCOPE_LOG_TAG(EncryptResources) + STEP_NAME(EncryptResources) }; } // namespace encryption diff --git a/src/wgt/step/encryption/step_remove_encryption_data.h b/src/wgt/step/encryption/step_remove_encryption_data.h index f372e39..0fe8d67 100644 --- a/src/wgt/step/encryption/step_remove_encryption_data.h +++ b/src/wgt/step/encryption/step_remove_encryption_data.h @@ -31,7 +31,7 @@ class StepRemoveEncryptionData : public common_installer::Step { Status undo() override { return Status::OK; } Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(RemoveEncryptionData) + STEP_NAME(RemoveEncryptionData) }; } // namespace encryption } // namespace wgt diff --git a/src/wgt/step/filesystem/step_copy_preview_icons.h b/src/wgt/step/filesystem/step_copy_preview_icons.h index ee9c525..5a51d83 100644 --- a/src/wgt/step/filesystem/step_copy_preview_icons.h +++ b/src/wgt/step/filesystem/step_copy_preview_icons.h @@ -26,7 +26,7 @@ class StepCopyPreviewIcons : public common_installer::Step { Status undo() override { return Status::OK; } Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(CopyPreviewIcons) + STEP_NAME(CopyPreviewIcons) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.h b/src/wgt/step/filesystem/step_create_symbolic_link.h index dbe650b..43b3ddb 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.h +++ b/src/wgt/step/filesystem/step_create_symbolic_link.h @@ -56,7 +56,7 @@ class StepCreateSymbolicLink : public common_installer::Step { bool CreateSymlinksForApps(); bool CreateSymlinksForAppWidgets(); - SCOPE_LOG_TAG(SymbolicLink) + STEP_NAME(SymbolicLink) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_wgt_patch_icons.h b/src/wgt/step/filesystem/step_wgt_patch_icons.h index d4ff8fb..1f478a5 100644 --- a/src/wgt/step/filesystem/step_wgt_patch_icons.h +++ b/src/wgt/step/filesystem/step_wgt_patch_icons.h @@ -28,7 +28,7 @@ class StepWgtPatchIcons : public common_installer::Step { Status clean() override { return Status::OK; } Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(WgtPatchIcons) + STEP_NAME(WgtPatchIcons) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_wgt_patch_storage_directories.h b/src/wgt/step/filesystem/step_wgt_patch_storage_directories.h index c3a61e9..f4ab56f 100644 --- a/src/wgt/step/filesystem/step_wgt_patch_storage_directories.h +++ b/src/wgt/step/filesystem/step_wgt_patch_storage_directories.h @@ -30,7 +30,7 @@ class StepWgtPatchStorageDirectories : bool ShareDirFor3x(); bool CreatePrivateTmpDir(); - SCOPE_LOG_TAG(PatchWgtStorageDirectories) + STEP_NAME(PatchWgtStorageDirectories) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_wgt_prepare_package_directory.h b/src/wgt/step/filesystem/step_wgt_prepare_package_directory.h index 6d35f30..dd98d4c 100644 --- a/src/wgt/step/filesystem/step_wgt_prepare_package_directory.h +++ b/src/wgt/step/filesystem/step_wgt_prepare_package_directory.h @@ -36,7 +36,7 @@ class StepWgtPreparePackageDirectory : public common_installer::Step { private: Status CreateSymlinkToMountPoint(); - SCOPE_LOG_TAG(WgtPreparePackageDirectory) + STEP_NAME(WgtPreparePackageDirectory) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_wgt_resource_directory.h b/src/wgt/step/filesystem/step_wgt_resource_directory.h index 7fa9a4c..f5437fd 100644 --- a/src/wgt/step/filesystem/step_wgt_resource_directory.h +++ b/src/wgt/step/filesystem/step_wgt_resource_directory.h @@ -53,7 +53,7 @@ class StepWgtResourceDirectory : public common_installer::Step { */ Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(CreateWgtResourceDirectory) + STEP_NAME(CreateWgtResourceDirectory) }; } // namespace filesystem diff --git a/src/wgt/step/filesystem/step_wgt_update_package_directory.h b/src/wgt/step/filesystem/step_wgt_update_package_directory.h index aa15c02..b8aefbb 100644 --- a/src/wgt/step/filesystem/step_wgt_update_package_directory.h +++ b/src/wgt/step/filesystem/step_wgt_update_package_directory.h @@ -24,7 +24,7 @@ class StepWgtUpdatePackageDirectory : public StepWgtPreparePackageDirectory { Status CreateBackupOfDirectories(); Status RecoverBackupOfDirectories(); - SCOPE_LOG_TAG(WgtUpdatePackageDirectory) + STEP_NAME(WgtUpdatePackageDirectory) }; } // namespace filesystem diff --git a/src/wgt/step/pkgmgr/step_generate_xml.h b/src/wgt/step/pkgmgr/step_generate_xml.h index 00b82e6..a00b9d3 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.h +++ b/src/wgt/step/pkgmgr/step_generate_xml.h @@ -37,7 +37,7 @@ class StepGenerateXml : public common_installer::Step { xmlTextWriterPtr writer, AppCompType type); - SCOPE_LOG_TAG(GenerateXML) + STEP_NAME(GenerateXML) }; } // namespace pkgmgr diff --git a/src/wgt/step/rds/step_wgt_rds_modify.h b/src/wgt/step/rds/step_wgt_rds_modify.h index 67f9d28..2812b5a 100644 --- a/src/wgt/step/rds/step_wgt_rds_modify.h +++ b/src/wgt/step/rds/step_wgt_rds_modify.h @@ -31,6 +31,8 @@ class StepWgtRDSModify : public common_installer::rds::StepRDSModify { * \return std::string */ std::string GetAppPath() override; + + STEP_NAME(WgtRDSModify) }; } // namespace rds diff --git a/src/wgt/step/security/step_add_default_privileges.h b/src/wgt/step/security/step_add_default_privileges.h index b7759a9..84c7bca 100644 --- a/src/wgt/step/security/step_add_default_privileges.h +++ b/src/wgt/step/security/step_add_default_privileges.h @@ -50,7 +50,7 @@ class StepAddDefaultPrivileges : public common_installer::Step { */ Status precheck() override; - SCOPE_LOG_TAG(AddDefaultPrivileges) + STEP_NAME(AddDefaultPrivileges) }; } // namespace security diff --git a/src/wgt/step/security/step_check_settings_level.h b/src/wgt/step/security/step_check_settings_level.h index 3dfd8ac..adc7337 100644 --- a/src/wgt/step/security/step_check_settings_level.h +++ b/src/wgt/step/security/step_check_settings_level.h @@ -50,7 +50,7 @@ class StepCheckSettingsLevel : public common_installer::Step { */ Status precheck() override { return Status::OK; } - SCOPE_LOG_TAG(CheckSettingsLevel) + STEP_NAME(CheckSettingsLevel) }; } // namespace security diff --git a/src/wgt/step/security/step_check_wgt_ime_privilege.h b/src/wgt/step/security/step_check_wgt_ime_privilege.h index d5595db..04f49c8 100644 --- a/src/wgt/step/security/step_check_wgt_ime_privilege.h +++ b/src/wgt/step/security/step_check_wgt_ime_privilege.h @@ -31,7 +31,7 @@ class StepCheckWgtImePrivilege : Status CheckImePrivilege() const; - SCOPE_LOG_TAG(CheckWgtImePrivilege) + STEP_NAME(CheckWgtImePrivilege) }; } // namespace security } // namespace wgt diff --git a/src/wgt/step/security/step_check_wgt_notification_category.h b/src/wgt/step/security/step_check_wgt_notification_category.h index 738a6ea..842b531 100644 --- a/src/wgt/step/security/step_check_wgt_notification_category.h +++ b/src/wgt/step/security/step_check_wgt_notification_category.h @@ -24,6 +24,8 @@ class StepCheckWgtNotificationCategory : Status clean() override { return Status::OK; } Status undo() override { return Status::OK; } Status precheck() override { return Status::OK; } + + STEP_NAME(CheckWgtNotificationCategory) }; } // namespace security } // namespace wgt diff --git a/src/wgt/step/security/step_direct_manifest_check_signature.h b/src/wgt/step/security/step_direct_manifest_check_signature.h index a24d910..a56a998 100644 --- a/src/wgt/step/security/step_direct_manifest_check_signature.h +++ b/src/wgt/step/security/step_direct_manifest_check_signature.h @@ -19,7 +19,7 @@ class StepDirectManifestCheckSignature private: boost::filesystem::path GetSignatureRoot() const override; - SCOPE_LOG_TAG(StepDirectManifestCheckSignature) + STEP_NAME(StepDirectManifestCheckSignature) }; } // namespace security -- 2.7.4 From 70f5b6d15f222869221b012499e40ebda3ac7f4b Mon Sep 17 00:00:00 2001 From: Piotr Ganicz Date: Wed, 25 May 2016 14:43:38 +0200 Subject: [PATCH 15/16] Refactoring of StepGenerateXml This patch provides refactoring for StepGenerateXml::process() method into smaller pieces. Change-Id: I3889f127bb4344a79cd18fb2875d6983a9ab20a7 --- src/wgt/step/pkgmgr/step_generate_xml.cc | 105 ++++++++++++++++++++++--------- src/wgt/step/pkgmgr/step_generate_xml.h | 13 ++++ 2 files changed, 87 insertions(+), 31 deletions(-) diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 6bf7403..724203d 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -243,6 +243,13 @@ common_installer::Step::Status StepGenerateXml::GenerateApplicationCommonXml( return Step::Status::OK; } +common_installer::Step::Status StepGenerateXml::undo() { + bs::error_code error; + if (bf::exists(context_->xml_path.get())) + bf::remove_all(context_->xml_path.get(), error); + return Status::OK; +} + common_installer::Step::Status StepGenerateXml::precheck() { if (!context_->manifest_data.get()) { LOG(ERROR) << "manifest_data attribute is empty"; @@ -278,7 +285,6 @@ common_installer::Step::Status StepGenerateXml::process() { } xmlTextWriterPtr writer; - writer = xmlNewTextWriterFilename(context_->xml_path.get().c_str(), 0); if (!writer) { LOG(ERROR) << "Failed to create new file"; @@ -286,12 +292,52 @@ common_installer::Step::Status StepGenerateXml::process() { } xmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr); - xmlTextWriterSetIndent(writer, 1); - // add manifest Element + Status status = GenerateManifestElement(writer); + if (status != Status::OK) { + return status; + } + + xmlTextWriterEndDocument(writer); + xmlFreeTextWriter(writer); + + if (pkgmgr_parser_check_manifest_validation( + context_->xml_path.get().c_str()) != 0) { + LOG(ERROR) << "Manifest is not valid"; + return Step::Status::MANIFEST_ERROR; + } + + LOG(DEBUG) << "Successfully create manifest xml " + << context_->xml_path.get(); + return Status::OK; +} + +common_installer::Step::Status StepGenerateXml::GenerateManifestElement( + xmlTextWriterPtr writer) { xmlTextWriterStartElement(writer, BAD_CAST "manifest"); + GenerateManifestElementAttributes(writer); + GenerateLangLabels(writer); + GenerateAuthor(writer); + GenerateDescription(writer); + Status status = GenerateApplications(writer); + if (status != Status::OK) { + return status; + } + GeneratePrivilege(writer); + GenerateAccount(writer); + GenerateIme(writer); + GenerateProfiles(writer); + GenerateShortcuts(writer); + GenerateWidget(writer); + + xmlTextWriterEndElement(writer); + return Status::OK; +} + +void StepGenerateXml::GenerateManifestElementAttributes( + xmlTextWriterPtr writer) { xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns", BAD_CAST "http://tizen.org/ns/packages"); xmlTextWriterWriteAttribute(writer, BAD_CAST "package", @@ -304,7 +350,9 @@ common_installer::Step::Status StepGenerateXml::process() { BAD_CAST context_->manifest_data.get()->api_version); xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay-setting", BAD_CAST context_->manifest_data.get()->nodisplay_setting); +} +void StepGenerateXml::GenerateLangLabels(xmlTextWriterPtr writer) { for (label_x* label : GListRange(context_->manifest_data.get()->label)) { xmlTextWriterStartElement(writer, BAD_CAST "label"); @@ -315,7 +363,9 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterWriteString(writer, BAD_CAST label->name); xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateAuthor(xmlTextWriterPtr writer) { for (author_x* author : GListRange(context_->manifest_data.get()->author)) { xmlTextWriterStartElement(writer, BAD_CAST "author"); @@ -330,7 +380,9 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterWriteString(writer, BAD_CAST author->text); xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateDescription(xmlTextWriterPtr writer) { for (description_x* description : GListRange(context_->manifest_data.get()->description)) { xmlTextWriterStartElement(writer, BAD_CAST "description"); @@ -341,8 +393,10 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterWriteString(writer, BAD_CAST description->text); xmlTextWriterEndElement(writer); } +} - // add application +common_installer::Step::Status StepGenerateXml::GenerateApplications( + xmlTextWriterPtr writer) { for (application_x* app : GListRange(context_->manifest_data.get()->application)) { AppCompType type; @@ -366,12 +420,11 @@ common_installer::Step::Status StepGenerateXml::process() { GenerateApplicationCommonXml(app, writer, type); xmlTextWriterEndElement(writer); } + return Status::OK; +} - const auto &ime = context_->manifest_plugins_data.get().ime_info.get(); - const auto ime_uuid = ime.uuid(); - - // add privilege element - if (context_->manifest_data.get()->privileges) { +void StepGenerateXml::GeneratePrivilege(xmlTextWriterPtr writer) { + if (context_->manifest_data.get()->privileges) { xmlTextWriterStartElement(writer, BAD_CAST "privileges"); for (const char* priv : GListRange(context_->manifest_data.get()->privileges)) { @@ -381,7 +434,9 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateAccount(xmlTextWriterPtr writer) { const auto& accounts = context_->manifest_plugins_data.get().account_info.get().accounts(); if (!accounts.empty()) { @@ -431,7 +486,11 @@ common_installer::Step::Status StepGenerateXml::process() { } xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateIme(xmlTextWriterPtr writer) { + const auto &ime = context_->manifest_plugins_data.get().ime_info.get(); + const auto ime_uuid = ime.uuid(); if (!ime_uuid.empty()) { xmlTextWriterStartElement(writer, BAD_CAST "ime"); @@ -461,7 +520,9 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateProfiles(xmlTextWriterPtr writer) { for (const char* profile : GListRange(context_->manifest_data.get()->deviceprofile)) { xmlTextWriterStartElement(writer, BAD_CAST "profile"); @@ -469,7 +530,9 @@ common_installer::Step::Status StepGenerateXml::process() { BAD_CAST profile); xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateShortcuts(xmlTextWriterPtr writer) { const auto& shortcuts = context_->manifest_plugins_data.get().shortcut_info.get(); if (!shortcuts.empty()) { @@ -502,7 +565,9 @@ common_installer::Step::Status StepGenerateXml::process() { } xmlTextWriterEndElement(writer); } +} +void StepGenerateXml::GenerateWidget(xmlTextWriterPtr writer) { WgtBackendData* backend_data = static_cast(context_->backend_data.get()); bf::path widget_content_path = context_->pkg_path.get() / kResWgt; @@ -573,28 +638,6 @@ common_installer::Step::Status StepGenerateXml::process() { xmlTextWriterEndElement(writer); } - - xmlTextWriterEndElement(writer); - - xmlTextWriterEndDocument(writer); - xmlFreeTextWriter(writer); - - if (pkgmgr_parser_check_manifest_validation( - context_->xml_path.get().c_str()) != 0) { - LOG(ERROR) << "Manifest is not valid"; - return Step::Status::MANIFEST_ERROR; - } - - LOG(DEBUG) << "Successfully create manifest xml " - << context_->xml_path.get(); - return Status::OK; -} - -common_installer::Step::Status StepGenerateXml::undo() { - bs::error_code error; - if (bf::exists(context_->xml_path.get())) - bf::remove_all(context_->xml_path.get(), error); - return Status::OK; } } // namespace pkgmgr diff --git a/src/wgt/step/pkgmgr/step_generate_xml.h b/src/wgt/step/pkgmgr/step_generate_xml.h index a00b9d3..f4be3a7 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.h +++ b/src/wgt/step/pkgmgr/step_generate_xml.h @@ -37,6 +37,19 @@ class StepGenerateXml : public common_installer::Step { xmlTextWriterPtr writer, AppCompType type); + Step::Status GenerateManifestElement(xmlTextWriterPtr writer); + void GenerateManifestElementAttributes(xmlTextWriterPtr writer); + void GenerateLangLabels(xmlTextWriterPtr writer); + void GenerateAuthor(xmlTextWriterPtr writer); + void GenerateDescription(xmlTextWriterPtr writer); + Step::Status GenerateApplications(xmlTextWriterPtr writer); + void GeneratePrivilege(xmlTextWriterPtr writer); + void GenerateAccount(xmlTextWriterPtr writer); + void GenerateIme(xmlTextWriterPtr writer); + void GenerateProfiles(xmlTextWriterPtr writer); + void GenerateShortcuts(xmlTextWriterPtr writer); + void GenerateWidget(xmlTextWriterPtr writer); + STEP_NAME(GenerateXML) }; -- 2.7.4 From ffed32d0f9f28668c0409507c5b71cc606cd8348 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Wed, 1 Jun 2016 13:29:06 +0200 Subject: [PATCH 16/16] Fix generating widget-application item This commit is based on: - https://review.tizen.org/gerrit/71796 The way it is changed is: - widget information is gathered in manifest_x structure and backend data because data that is created by StepParse is inserted into database directly according to past changes (even we add widget information to generated manifest it is not read). - icon path is full path for widget-application (same as for ui-application) to handle icon backup, copying and pkgmgr expectations. - is changed to defined in manifest.xsd.in in pkgmgr-info repository. Requires: - https://review.tizen.org/gerrit/71798 - https://review.tizen.org/gerrit/72573 Change-Id: I2c980ae205f29fb70928aba58d8d3458d88a9c90 --- src/wgt/step/configuration/step_parse.cc | 82 ++++++++++--- src/wgt/step/configuration/step_parse.h | 1 + .../step/filesystem/step_create_symbolic_link.cc | 23 +--- .../step/filesystem/step_create_symbolic_link.h | 1 - src/wgt/step/pkgmgr/step_generate_xml.cc | 128 ++++++++------------- src/wgt/step/pkgmgr/step_generate_xml.h | 1 - 6 files changed, 115 insertions(+), 121 deletions(-) diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index ad485ca..ee937d2 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -84,6 +84,17 @@ void SetApplicationXDefaults(application_x* application) { application->ui_gadget = strdup("false"); } +template +void AppendLabel(T* root, const std::string& label, + const std::string& locale) { + label_x* label_item = reinterpret_cast(calloc(1, sizeof(label_x))); + label_item->name = strdup(label.c_str()); + label_item->text = strdup(label.c_str()); + label_item->lang = !locale.empty() ? + strdup(locale.c_str()) : strdup(DEFAULT_LOCALE); + root->label = g_list_append(root->label, label_item); +} + } // namespace namespace wgt { @@ -182,12 +193,7 @@ bool StepParse::FillWidgetInfo(manifest_x* manifest) { } for (auto& item : wgt_info->name_set()) { - label_x* label = reinterpret_cast(calloc(1, sizeof(label_x))); - label->name = strdup(item.second.c_str()); - label->text = strdup(item.second.c_str()); - label->lang = !item.first.empty() ? - strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE); - manifest->label = g_list_append(manifest->label, label); + AppendLabel(manifest, item.second, item.first); } manifest->type = strdup("wgt"); @@ -199,12 +205,7 @@ bool StepParse::FillWidgetInfo(manifest_x* manifest) { for (auto& item : wgt_info->name_set()) { application_x* app = reinterpret_cast(manifest->application->data); - label_x* label = reinterpret_cast(calloc(1, sizeof(label_x))); - label->name = strdup(item.second.c_str()); - label->text = strdup(item.second.c_str()); - label->lang = !item.first.empty() ? - strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE); - app->label = g_list_append(app->label, label); + AppendLabel(app, item.second, item.first); } author_x* author = reinterpret_cast(calloc(1, sizeof(author_x))); @@ -337,12 +338,7 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { application->package = strdup(manifest->package); for (auto& pair : service_info.names()) { - label_x* label = reinterpret_cast(calloc(1, sizeof(label_x))); - label->lang = !pair.first.empty() ? - strdup(pair.first.c_str()) : strdup(DEFAULT_LOCALE); - label->name = strdup(pair.second.c_str()); - label->text = strdup(pair.second.c_str()); - application->label = g_list_append(application->label, label); + AppendLabel(application, pair.second, pair.first); } if (!service_info.icon().empty()) { @@ -373,6 +369,51 @@ bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) { return true; } +bool StepParse::FillWidgetApplicationInfo(manifest_x* manifest) { + std::shared_ptr appwidget_info = + std::static_pointer_cast( + parser_->GetManifestData( + wgt::application_widget_keys::kTizenAppWidgetFullKey)); + if (!appwidget_info) + return true; + for (auto& app_widget : appwidget_info->app_widgets()) { + application_x* application = reinterpret_cast + (calloc(1, sizeof(application_x))); + application->component_type = strdup("widgetapp"); + application->mainapp = strdup("false"); + application->multiple = strdup("false"); + application->appid = strdup(app_widget.id.c_str()); + application->exec = + strdup((context_->root_application_path.get() / manifest->package + / "bin" / application->appid).c_str()); + application->type = strdup("webapp"); + application->nodisplay = strdup("false"); + application->taskmanage = strdup("false"); + SetApplicationXDefaults(application); + application->ambient_support = strdup("false"); + application->package = strdup(manifest->package); + + if (!app_widget.label.default_value.empty()) { + AppendLabel(application, app_widget.label.default_value, std::string()); + } + + for (auto& pair : app_widget.label.lang_value_map) { + AppendLabel(application, pair.second, pair.first); + } + + if (!app_widget.icon_src.empty()) { + icon_x* icon = reinterpret_cast(calloc(1, sizeof(icon_x))); + icon->text = strdup(app_widget.icon_src.c_str()); + icon->lang = strdup(DEFAULT_LOCALE); + application->icon = g_list_append(application->icon, icon); + } + + manifest->application = g_list_append(manifest->application, application); + } + return true; +} + + bool StepParse::FillBackgroundCategoryInfo(manifest_x* manifest) { auto manifest_data = parser_->GetManifestData( app_keys::kTizenBackgroundCategoryKey); @@ -459,6 +500,7 @@ bool StepParse::FillMetadata(manifest_x* manifest) { } bool StepParse::FillAppWidget() { + // This is needed to store preview icons which are not saved into manifest_x WgtBackendData* backend_data = static_cast(context_->backend_data.get()); @@ -533,9 +575,11 @@ bool StepParse::FillManifestX(manifest_x* manifest) { // TODO(t.iwanek): fix adding ui application element // for now adding application service is added here because rest of code // assumes that there is one application at manifest->application - // so this must execute last + // so this must execute last. Don't move it above any item if (!FillServiceApplicationInfo(manifest)) return false; + if (!FillWidgetApplicationInfo(manifest)) + return false; if (!FillBackgroundCategoryInfo(manifest)) return false; if (!FillExtraManifestInfo(manifest)) diff --git a/src/wgt/step/configuration/step_parse.h b/src/wgt/step/configuration/step_parse.h index eb7e7fa..e7b9357 100644 --- a/src/wgt/step/configuration/step_parse.h +++ b/src/wgt/step/configuration/step_parse.h @@ -59,6 +59,7 @@ class StepParse : public common_installer::Step { bool FillWidgetInfo(manifest_x* manifest); bool FillMainApplicationInfo(manifest_x* manifest); bool FillServiceApplicationInfo(manifest_x* manifest); + bool FillWidgetApplicationInfo(manifest_x* manifest); bool FillAppControl(manifest_x* manifest); bool FillPrivileges(manifest_x* manifest); bool FillCategories(manifest_x* manifest); diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.cc b/src/wgt/step/filesystem/step_create_symbolic_link.cc index b23fcae..bc94fe2 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.cc +++ b/src/wgt/step/filesystem/step_create_symbolic_link.cc @@ -17,8 +17,6 @@ #include #include -#include "wgt/wgt_backend_data.h" - namespace bf = boost::filesystem; namespace bs = boost::system; @@ -49,6 +47,8 @@ bool StepCreateSymbolicLink::CreateSymlinksForApps() { bf::create_symlink(bf::path(WRT_LAUNCHER), exec_path, error); } else if (strcmp(app->component_type, "watchapp") == 0) { bf::create_symlink(bf::path(WRT_LAUNCHER), exec_path, error); + } else if (strcmp(app->component_type, "widgetapp") == 0) { + bf::create_symlink(kWidgetClientBinaryPath, exec_path, error); } else { bf::create_symlink(kWrtServiceBinaryPath, exec_path, error); } @@ -61,31 +61,12 @@ bool StepCreateSymbolicLink::CreateSymlinksForApps() { return true; } -bool StepCreateSymbolicLink::CreateSymlinksForAppWidgets() { - WgtBackendData* backend_data = - static_cast(context_->backend_data.get()); - for (auto& appwidget : backend_data->appwidgets.get().app_widgets()) { - bf::path exec_path = context_->pkg_path.get() / "bin" / appwidget.id; - bs::error_code error; - bf::create_symlink(kWidgetClientBinaryPath, exec_path, error); - if (error) { - LOG(ERROR) << "Failed to create symlink for app widget: " - << appwidget.id; - return false; - } - } - return true; -} - common_installer::Step::Status StepCreateSymbolicLink::process() { assert(context_->manifest_data.get()); if (!CreateSymlinksForApps()) return Status::APP_DIR_ERROR; - if (!CreateSymlinksForAppWidgets()) - return Status::APP_DIR_ERROR; - LOG(DEBUG) << "Symlinks created successfully"; return Status::OK; } diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.h b/src/wgt/step/filesystem/step_create_symbolic_link.h index 43b3ddb..048c759 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.h +++ b/src/wgt/step/filesystem/step_create_symbolic_link.h @@ -54,7 +54,6 @@ class StepCreateSymbolicLink : public common_installer::Step { private: bool CreateSymlinksForApps(); - bool CreateSymlinksForAppWidgets(); STEP_NAME(SymbolicLink) }; diff --git a/src/wgt/step/pkgmgr/step_generate_xml.cc b/src/wgt/step/pkgmgr/step_generate_xml.cc index 724203d..1148642 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.cc +++ b/src/wgt/step/pkgmgr/step_generate_xml.cc @@ -84,18 +84,54 @@ void WriteServiceApplicationAttributes( BAD_CAST app->taskmanage); } -void WriteWidgetApplicationAttributes( - xmlTextWriterPtr writer, application_x *app) { +bool WriteWidgetApplicationAttributesAndElements( + xmlTextWriterPtr writer, application_x *app, + const wgt::parse::AppWidgetInfo& widget_info, + const bf::path& shared_path) { if (app->nodisplay) xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay", BAD_CAST app->nodisplay); if (app->multiple) xmlTextWriterWriteAttribute(writer, BAD_CAST "multiple", BAD_CAST app->multiple); + + // Generate attributes and elements not covered in manifest.xsd + auto& appwidgets = widget_info.app_widgets(); + const auto& appwidget = std::find_if(appwidgets.begin(), appwidgets.end(), + [app](const wgt::parse::AppWidget& widget) { + return widget.id == app->appid; + }); + if (appwidget == appwidgets.end()) { + LOG(ERROR) << "Failed to generate appwidget extra elements"; + return false; + } + + xmlTextWriterWriteAttribute(writer, BAD_CAST "main", + BAD_CAST (appwidget->primary ? "true" : "false")); // NOLINT + xmlTextWriterWriteAttribute(writer, BAD_CAST "update-period", BAD_CAST "0"); + + for (auto& size : appwidget->content_size) { + xmlTextWriterStartElement(writer, BAD_CAST "support-size"); + + std::string type = wgt::parse::AppWidgetSizeTypeToString(size.type); + if (!size.preview.empty()) { + std::string icon_name = shared_path.string() + "/" + appwidget->id + "." + type + "." + "preview" + + bf::path(size.preview).extension().string(); + xmlTextWriterWriteAttribute(writer, BAD_CAST "preview", + BAD_CAST icon_name.c_str()); // NOLINT + } + + xmlTextWriterWriteAttribute(writer, BAD_CAST "frame", + BAD_CAST "true"); + xmlTextWriterWriteString(writer, + BAD_CAST type.c_str()); + xmlTextWriterEndElement(writer); + } + return true; } void WriteWatchApplicationAttributes( - xmlTextWriterPtr writer, application_x *app) { + xmlTextWriterPtr writer, application_x* app) { if (app->ambient_support) xmlTextWriterWriteAttribute(writer, BAD_CAST "ambient-support", BAD_CAST app->ambient_support); @@ -132,7 +168,11 @@ common_installer::Step::Status StepGenerateXml::GenerateApplicationCommonXml( WriteServiceApplicationAttributes(writer, app); break; case AppCompType::WIDGETAPP: - WriteWidgetApplicationAttributes(writer, app); + if (!WriteWidgetApplicationAttributesAndElements(writer, app, + static_cast( + context_->backend_data.get())->appwidgets.get(), + context_->pkg_path.get() / "shared" / "res")) + return Status::MANIFEST_ERROR; break; case AppCompType::WATCHAPP: WriteWatchApplicationAttributes(writer, app); @@ -330,7 +370,6 @@ common_installer::Step::Status StepGenerateXml::GenerateManifestElement( GenerateIme(writer); GenerateProfiles(writer); GenerateShortcuts(writer); - GenerateWidget(writer); xmlTextWriterEndElement(writer); return Status::OK; @@ -417,7 +456,11 @@ common_installer::Step::Status StepGenerateXml::GenerateApplications( xmlFreeTextWriter(writer); return Status::ERROR; } - GenerateApplicationCommonXml(app, writer, type); + Status status = GenerateApplicationCommonXml(app, writer, type); + if (status != Status::OK) { + xmlFreeTextWriter(writer); + return status; + } xmlTextWriterEndElement(writer); } return Status::OK; @@ -567,78 +610,5 @@ void StepGenerateXml::GenerateShortcuts(xmlTextWriterPtr writer) { } } -void StepGenerateXml::GenerateWidget(xmlTextWriterPtr writer) { - WgtBackendData* backend_data = - static_cast(context_->backend_data.get()); - bf::path widget_content_path = context_->pkg_path.get() / kResWgt; - for (auto& appwidget : backend_data->appwidgets.get().app_widgets()) { - xmlTextWriterStartElement(writer, BAD_CAST "widget"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "appid", - BAD_CAST appwidget.id.c_str()); - xmlTextWriterWriteAttribute(writer, BAD_CAST "primary", - BAD_CAST (appwidget.primary ? "true" : "false")); // NOLINT - xmlTextWriterWriteAttribute(writer, BAD_CAST "abi", - BAD_CAST "html"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "network", - BAD_CAST "true"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay", - BAD_CAST "false"); - - if (!appwidget.label.default_value.empty()) { - xmlTextWriterStartElement(writer, BAD_CAST "label"); - xmlTextWriterWriteString(writer, - BAD_CAST appwidget.label.default_value.c_str()); - xmlTextWriterEndElement(writer); - } - for (auto& pair : appwidget.label.lang_value_map) { - xmlTextWriterStartElement(writer, BAD_CAST "label"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang", - BAD_CAST pair.first.c_str()); - xmlTextWriterWriteString(writer, BAD_CAST pair.second.c_str()); - xmlTextWriterEndElement(writer); - } - - if (!appwidget.icon_src.empty()) { - xmlTextWriterStartElement(writer, BAD_CAST "icon"); - xmlTextWriterWriteString(writer, BAD_CAST appwidget.icon_src.c_str()); - xmlTextWriterEndElement(writer); - } - - xmlTextWriterStartElement(writer, BAD_CAST "box"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST "buffer"); - xmlTextWriterWriteAttribute(writer, BAD_CAST "mouse_event", - BAD_CAST (appwidget.content_mouse_event ? "true" : "false")); // NOLINT - xmlTextWriterWriteAttribute(writer, BAD_CAST "touch_effect", - BAD_CAST (appwidget.content_touch_effect ? "true" : "false")); // NOLINT - xmlTextWriterStartElement(writer, BAD_CAST "script"); - bf::path src = widget_content_path / appwidget.content_src; - xmlTextWriterWriteAttribute(writer, BAD_CAST "src", - BAD_CAST src.c_str()); - xmlTextWriterEndElement(writer); - for (auto& size : appwidget.content_size) { - xmlTextWriterStartElement(writer, BAD_CAST "size"); - - std::string type = wgt::parse::AppWidgetSizeTypeToString(size.type); - if (!size.preview.empty()) { - std::string icon_name = appwidget.id + "." + type + "." + "preview" + - bf::path(size.preview).extension().string(); - bf::path preview_icon = - context_->pkg_path.get() / kSharedRes / icon_name; - xmlTextWriterWriteAttribute(writer, BAD_CAST "preview", - BAD_CAST preview_icon.c_str()); // NOLINT - } - - xmlTextWriterWriteAttribute(writer, BAD_CAST "need_frame", - BAD_CAST "true"); - xmlTextWriterWriteString(writer, - BAD_CAST type.c_str()); - xmlTextWriterEndElement(writer); - } - xmlTextWriterEndElement(writer); - - xmlTextWriterEndElement(writer); - } -} - } // namespace pkgmgr } // namespace wgt diff --git a/src/wgt/step/pkgmgr/step_generate_xml.h b/src/wgt/step/pkgmgr/step_generate_xml.h index f4be3a7..5dbb706 100644 --- a/src/wgt/step/pkgmgr/step_generate_xml.h +++ b/src/wgt/step/pkgmgr/step_generate_xml.h @@ -48,7 +48,6 @@ class StepGenerateXml : public common_installer::Step { void GenerateIme(xmlTextWriterPtr writer); void GenerateProfiles(xmlTextWriterPtr writer); void GenerateShortcuts(xmlTextWriterPtr writer); - void GenerateWidget(xmlTextWriterPtr writer); STEP_NAME(GenerateXML) }; -- 2.7.4