From d1168a645ff3b62db3d56c9072d18565880398c5 Mon Sep 17 00:00:00 2001 From: Tomasz Iwanek Date: Tue, 26 May 2015 15:31:41 +0200 Subject: [PATCH] Workaround for update installation detection This workaround is provided as pkgmgr requested. This should be removed as soon as pkgmgr will handle update detection and be passing correct options. Removal of this should be easy as it is not modifing any flow in installer. Depends on pkgmgr: https://review.tizen.org/gerrit/#/c/38771/ Change-Id: Idae3b4ffd7842babc555c717986fe9beac39fece --- src/wgt/CMakeLists.txt | 1 + src/wgt/update_workaround.cc | 125 +++++++++++++++++++++++++++++++++++++++++++ src/wgt/update_workaround.h | 14 +++++ src/wgt/wgt_backend.cc | 7 ++- 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/wgt/update_workaround.cc create mode 100644 src/wgt/update_workaround.h diff --git a/src/wgt/CMakeLists.txt b/src/wgt/CMakeLists.txt index a54575c..2cb946c 100644 --- a/src/wgt/CMakeLists.txt +++ b/src/wgt/CMakeLists.txt @@ -2,6 +2,7 @@ SET(SRCS step/step_parse.cc step/step_create_symbolic_link.cc + update_workaround.cc wgt_backend.cc ) diff --git a/src/wgt/update_workaround.cc b/src/wgt/update_workaround.cc new file mode 100644 index 0000000..944cc02 --- /dev/null +++ b/src/wgt/update_workaround.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache 2.0 license that can be +// found in the LICENSE file. + +#include "wgt/update_workaround.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "utils/file_util.h" +#include "utils/logging.h" + +namespace bf = boost::filesystem; +namespace bs = boost::system; + +namespace { + +std::pair GetInstallationPackagePath(int argc, char** argv) { + int index = -1; + std::string path; + for (unsigned i = 0; i < argc; ++i) { + if (!strcmp(argv[i], "-i")) { + index = i; + if (i + 1 < argc) { + path = argv[i + 1]; + } + break; + } + } + return std::make_pair(path, index); +} + +std::string GetAppIdFromPath(const std::string& path) { + bf::path tmp_path = common_installer::utils::GenerateTmpDir("/tmp"); + bs::error_code code; + bf::create_directories(tmp_path, code); + if (code) + return {}; + if (!common_installer::utils::ExtractToTmpDir(path.c_str(), tmp_path, + "config.xml")) { + bf::remove_all(tmp_path, code); + return {}; + } + bf::path config_path = tmp_path / "config.xml"; + std::vector handlers = { + new wgt::parse::WidgetHandler(), + new wgt::parse::TizenApplicationHandler() + }; + std::unique_ptr registry( + new parser::ManifestHandlerRegistry(handlers)); + std::unique_ptr parser( + new parser::ManifestParser(std::move(registry))); + if (!parser->ParseManifest(config_path)) { + bf::remove_all(tmp_path, code); + return {}; + } + auto info = std::static_pointer_cast( + parser->GetManifestData( + wgt::application_widget_keys::kTizenApplicationKey)); + if (!info) { + bf::remove_all(tmp_path, code); + return {}; + } + std::string pkg_id = info->package(); + + bf::remove_all(tmp_path, code); + return pkg_id; +} + +bool IsPackageInstalled(const std::string& pkg_id) { + pkgmgrinfo_pkginfo_h handle; + int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(), + &handle); + if (ret != PMINFO_R_OK) + return false; + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return true; +} + +void OverwriteArgvForUpdate(int index, char** argv) { + // overwriting argv to fake update + argv[index][1] = 'a'; +} + +} // namespace + +namespace workaround { + +void OverwriteArgvIfNeeded(int argc, char** argv) { + std::string path; + int index; + std::tie(path, index) = + GetInstallationPackagePath(argc, argv); + if (path.empty()) { + // not the installaton + return; + } + std::string pkg_id = GetAppIdFromPath(path); + if (pkg_id.empty()) + return; + bool should_hack = IsPackageInstalled(pkg_id); + if (should_hack) { + LOG(INFO) << "Update detected - hacking argv to update installation"; + OverwriteArgvForUpdate(index, argv); + } +} + +} // namespace workaround diff --git a/src/wgt/update_workaround.h b/src/wgt/update_workaround.h new file mode 100644 index 0000000..bb455af --- /dev/null +++ b/src/wgt/update_workaround.h @@ -0,0 +1,14 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache 2.0 license that can be +// found in the LICENSE file. + +#ifndef WGT_UPDATE_WORKAROUND_H_ +#define WGT_UPDATE_WORKAROUND_H_ + +namespace workaround { + +void OverwriteArgvIfNeeded(int argc, char** argv); + +} // namespace workaround + +#endif // WGT_UPDATE_WORKAROUND_H_ diff --git a/src/wgt/wgt_backend.cc b/src/wgt/wgt_backend.cc index 34c1f39..fb2d699 100644 --- a/src/wgt/wgt_backend.cc +++ b/src/wgt/wgt_backend.cc @@ -24,13 +24,18 @@ #include "common/step/step_unzip.h" #include "common/step/step_update_app.h" #include "common/step/step_update_security.h" + +#include "wgt/update_workaround.h" + #include "wgt/step/step_parse.h" #include "wgt/step/step_create_symbolic_link.h" - namespace ci = common_installer; int main(int argc, char** argv) { + // TODO(t.iwanek): remove this when update installation detection is ready + workaround::OverwriteArgvIfNeeded(argc, argv); + int result = ci::PkgMgrInterface::Init(argc, argv); if (result) { LOG(ERROR) << "Cannot connect to PkgMgrInstaller"; -- 2.7.4