From ee1a6f46c164704f34e2503501337afc94e0e1ab Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Wed, 18 May 2016 08:02:55 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 11/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 From 761a13058814f05500026601bbe67dcfd7aa8987 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Mon, 13 Jun 2016 15:51:02 +0900 Subject: [PATCH 12/16] set label to prevent execution by non-system application. Change-Id: I12e682b56fa142919ef1d6941d995b7874cab130 Signed-off-by: jongmyeongko --- packaging/wgt-backend.manifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/wgt-backend.manifest b/packaging/wgt-backend.manifest index 55125da..85f79f1 100644 --- a/packaging/wgt-backend.manifest +++ b/packaging/wgt-backend.manifest @@ -3,6 +3,6 @@ - + -- 2.7.4 From c487e4bf613524114db57876f33790a7a0b66a3d Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Mon, 13 Jun 2016 16:45:48 +0900 Subject: [PATCH 13/16] Add StepCheckRestriction Added at install, uninstall, reinstall, mount install. Change-Id: I85ff7e43ac8b9033654b116b436a0db04953572f Signed-off-by: Sangyoon Jang --- src/hybrid/hybrid_installer.cc | 4 ++++ src/wgt/wgt_installer.cc | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc index c1765cc..b54c8e5 100644 --- a/src/hybrid/hybrid_installer.cc +++ b/src/hybrid/hybrid_installer.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -167,6 +169,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) break; case ci::RequestType::Uninstall: AddStep(pkgmgr_); + AddStep(); AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, @@ -264,6 +267,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr) AddStep( wgt::configuration::StepParse::ConfigLocation::RESOURCE_WGT, true); AddStep(); + AddStep(); AddStep(); AddStep(); AddStep(); diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 13176b2..11b7c9b 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); @@ -163,6 +165,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) } case ci::RequestType::Uninstall: { AddStep(pkgmgr_); + AddStep(); AddStep(); AddStep( ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, @@ -186,6 +189,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(pkgmgr_); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, false); + AddStep(); AddStep(); AddStep(); AddStep( @@ -269,6 +273,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); AddStep( wgt::configuration::StepParse::ConfigLocation::PACKAGE, true); + AddStep(); AddStep(); AddStep(); AddStep(); -- 2.7.4 From 487c97263f921ed473549f6c6022827e50ff33f1 Mon Sep 17 00:00:00 2001 From: JongHeon Choi Date: Thu, 9 Jun 2016 11:30:12 +0900 Subject: [PATCH 14/16] Change the binary name.(widget-client => web-widget-runtime) Change-Id: If3da83217bd4e3739079689697a56b5454b714e0 --- src/wgt/step/filesystem/step_create_symbolic_link.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wgt/step/filesystem/step_create_symbolic_link.cc b/src/wgt/step/filesystem/step_create_symbolic_link.cc index bc94fe2..cbdbb7f 100644 --- a/src/wgt/step/filesystem/step_create_symbolic_link.cc +++ b/src/wgt/step/filesystem/step_create_symbolic_link.cc @@ -23,7 +23,7 @@ namespace bs = boost::system; namespace { const char kWrtServiceBinaryPath[] = "/usr/bin/wrt-service"; -const char kWidgetClientBinaryPath[] = "/usr/bin/widget-client"; +const char kWebWidgetRuntimeBinaryPath[] = "/usr/bin/web-widget-runtime"; } // namespace @@ -48,7 +48,7 @@ bool StepCreateSymbolicLink::CreateSymlinksForApps() { } 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); + bf::create_symlink(kWebWidgetRuntimeBinaryPath, exec_path, error); } else { bf::create_symlink(kWrtServiceBinaryPath, exec_path, error); } -- 2.7.4 From 810e4243029550e4861625943e8bd949023097b8 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Thu, 16 Jun 2016 20:39:59 +0900 Subject: [PATCH 15/16] apply PIE option Change-Id: I7d3271747ff9be58b0f8a46637a8282000c59b3c Signed-off-by: jongmyeongko --- CMakeLists.txt | 23 ++++++++++++----------- src/hybrid/CMakeLists.txt | 1 + src/unit_tests/CMakeLists.txt | 6 +++--- src/wgt/CMakeLists.txt | 1 + src/wgt_backend/CMakeLists.txt | 2 ++ 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08858fa..20eafb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,13 +13,18 @@ IF(NOT CMAKE_BUILD_TYPE) ENDIF(NOT CMAKE_BUILD_TYPE) # Compiler flags -SET(CMAKE_C_FLAGS_PROFILING "-O2") -SET(CMAKE_CXX_FLAGS_PROFILING "-O2 -std=c++11") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") -SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++11 -g") -SET(CMAKE_C_FLAGS_RELEASE "-O2 -g") -SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -std=c++11 -g") -SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++11 -g --coverage") +SET(EXTRA_FLAGS "-Wall -Wextra") +SET(CMAKE_C_FLAGS_PROFILING "-O2 ${EXTRA_FLAGS}") +SET(CMAKE_CXX_FLAGS_PROFILING "-O2 -std=c++11 ${EXTRA_FLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g ${EXTRA_FLAGS}") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++11 -g ${EXTRA_FLAGS}") +SET(CMAKE_C_FLAGS_RELEASE "-O2 -g ${EXTRA_FLAGS}") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -std=c++11 -g ${EXTRA_FLAGS}") +SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++11 -g --coverage ${EXTRA_FLAGS}") + +# Linker flags +SET(EXTRA_LINKER_FLAGS "-Wl,--as-needed") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EXTRA_LINKER_FLAGS}") # Targets SET(TARGET_LIBNAME_WGT "wgt-installer") @@ -30,10 +35,6 @@ SET(TARGET_SMOKE_TEST "smoke-test") SET(TARGET_SMOKE_TEST_HELPER "smoke-test-helper") SET(TARGET_MANIFEST_TEST "manifest-test") -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/") diff --git a/src/hybrid/CMakeLists.txt b/src/hybrid/CMakeLists.txt index 72cc3d2..ccc7f4a 100644 --- a/src/hybrid/CMakeLists.txt +++ b/src/hybrid/CMakeLists.txt @@ -16,3 +16,4 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_HYBRID} PUBLIC # Target - in-package deps TARGET_LINK_LIBRARIES(${TARGET_LIBNAME_HYBRID} PRIVATE ${TARGET_LIBNAME_WGT}) +SET_TARGET_PROPERTIES(${TARGET_LIBNAME_HYBRID} PROPERTIES COMPILE_FLAGS "-fPIC") diff --git a/src/unit_tests/CMakeLists.txt b/src/unit_tests/CMakeLists.txt index 7222f1e..3947045 100644 --- a/src/unit_tests/CMakeLists.txt +++ b/src/unit_tests/CMakeLists.txt @@ -29,9 +29,9 @@ APPLY_PKG_CONFIG(${TARGET_MANIFEST_TEST} PUBLIC # 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(${TARGET_SMOKE_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_HYBRID} ${GTEST_MAIN_LIBRARIES}) -target_link_libraries(${TARGET_SMOKE_TEST_HELPER} PRIVATE ${TARGET_LIBNAME_WGT}) -target_link_libraries(${TARGET_MANIFEST_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${GTEST_MAIN_LIBRARIES}) +TARGET_LINK_LIBRARIES(${TARGET_SMOKE_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${TARGET_LIBNAME_HYBRID} ${GTEST_MAIN_LIBRARIES}) +TARGET_LINK_LIBRARIES(${TARGET_SMOKE_TEST_HELPER} PRIVATE ${TARGET_LIBNAME_WGT}) +TARGET_LINK_LIBRARIES(${TARGET_MANIFEST_TEST} PRIVATE ${TARGET_LIBNAME_WGT} ${GTEST_MAIN_LIBRARIES}) INSTALL(TARGETS ${TARGET_SMOKE_TEST} DESTINATION ${BINDIR}/${DESTINATION_DIR}) INSTALL(TARGETS ${TARGET_SMOKE_TEST_HELPER} DESTINATION ${BINDIR}/${DESTINATION_DIR}) diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index ea51011..f45acc5 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -42,3 +42,4 @@ APPLY_PKG_CONFIG(${TARGET_LIBNAME_WGT} PUBLIC ENCRYPTION_DEPS Boost ) +SET_TARGET_PROPERTIES(${TARGET_LIBNAME_WGT} PROPERTIES COMPILE_FLAGS "-fPIC") diff --git a/src/wgt_backend/CMakeLists.txt b/src/wgt_backend/CMakeLists.txt index 54f886e..79807f6 100644 --- a/src/wgt_backend/CMakeLists.txt +++ b/src/wgt_backend/CMakeLists.txt @@ -6,6 +6,8 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_WGT_BACKEND} PUBLIC "${CMAKE_CURRENT_SOURCE_ # Target - in-package deps TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PRIVATE ${TARGET_LIBNAME_WGT}) TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PRIVATE ${TARGET_LIBNAME_HYBRID}) +SET_TARGET_PROPERTIES(${TARGET_WGT_BACKEND} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE") +SET_TARGET_PROPERTIES(${TARGET_WGT_BACKEND} PROPERTIES LINK_FLAGS "-pie") # Install INSTALL(TARGETS ${TARGET_WGT_BACKEND} DESTINATION ${BINDIR}) -- 2.7.4 From e4076b741c3091c2bdebf422dbed000e2b4e59f2 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Fri, 10 Jun 2016 12:58:58 +0200 Subject: [PATCH 16/16] Implement move request for wgt-backend Check success of commands to verify: wgt-backend -i ${package} wgt-backend -m ${pkgid} -t 1 wgt-backend -m ${pkgid} -t 2 Change-Id: I72ef419c1b4c5f99b3477265a7549a53c5efa838 --- src/wgt/step/configuration/step_parse.cc | 1 + src/wgt/wgt_installer.cc | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/wgt/step/configuration/step_parse.cc b/src/wgt/step/configuration/step_parse.cc index ee937d2..51c86ca 100644 --- a/src/wgt/step/configuration/step_parse.cc +++ b/src/wgt/step/configuration/step_parse.cc @@ -200,6 +200,7 @@ bool StepParse::FillWidgetInfo(manifest_x* manifest) { manifest->appsetting = strdup("false"); manifest->nodisplay_setting = strdup("false"); manifest->preload = strdup("false"); + manifest->installed_storage = strdup("installed_internal"); // For wgt package use the long name for (auto& item : wgt_info->name_set()) { diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc index 11b7c9b..bfa2b4e 100644 --- a/src/wgt/wgt_installer.cc +++ b/src/wgt/wgt_installer.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -377,6 +378,16 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr) AddStep(); break; } + case ci::RequestType::Move: { + AddStep(pkgmgr_); + AddStep( + ci::configuration::StepParseManifest::ManifestLocation::INSTALLED, + ci::configuration::StepParseManifest::StoreLocation::NORMAL); + AddStep(); + AddStep(); + AddStep(); + break; + } default: { AddStep(); } -- 2.7.4