From: Tomasz Iwanek Date: Wed, 4 Feb 2015 12:22:44 +0000 (+0100) Subject: Send pkgmgr signal always X-Git-Tag: submit/tizen_mobile/20150224.012613~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84c9d04aa808fe447d4b230d60ac56ecff979ceb;p=platform%2Fcore%2Fappfw%2Fapp-installers.git Send pkgmgr signal always Zip or config.xml can be malformed. This fixes handling signalling in those cases. Code which handles pkgmgr signal was extracted into - src/common/pkgmgr_signal.* Change-Id: I46b96f6ba8cd2c41110f2fefbceb6dc1b2969216 --- diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9c8dea8..8b2ef6b 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -2,6 +2,7 @@ SET(SRCS app_installer.cc context_installer.cc + pkgmgr_signal.cc security_registration.cc step/step_unzip.cc step/step_signature.cc diff --git a/src/common/app_installer.cc b/src/common/app_installer.cc index 8bfb153..cef0eb1 100644 --- a/src/common/app_installer.cc +++ b/src/common/app_installer.cc @@ -5,13 +5,14 @@ #include "common/app_installer.h" #include "common/context_installer.h" +#include "common/pkgmgr_signal.h" namespace common_installer { -AppInstaller::AppInstaller(pkgmgr_installer *pi) { - context_.reset(new ContextInstaller()); +AppInstaller::AppInstaller(pkgmgr_installer *pi) + : context_(new ContextInstaller()) { int request_type = pkgmgr_installer_get_request_type(pi); - context_->set_pi(pi); + context_->set_pi(std::unique_ptr(new PkgmgrSignal(pi))); context_->set_request_type(request_type); switch (request_type) { case PKGMGR_REQ_INSTALL: @@ -28,6 +29,14 @@ AppInstaller::AppInstaller(pkgmgr_installer *pi) { AppInstaller::~AppInstaller() { } +void AppInstaller::EnsureSignalSend() { + if (!context_->pi()->IsFinished()) { + // if signal was not sent during normal step execution + // then this will sent any signal about failure + (void) context_->pi()->sendStarted(); + (void) context_->pi()->sendFinished(PkgmgrSignal::Result::FAILED); + } +} int AppInstaller::Run() { std::list>::iterator it(steps_.begin()); @@ -59,6 +68,9 @@ int AppInstaller::Run() { } } } + + EnsureSignalSend(); + return ret; } diff --git a/src/common/app_installer.h b/src/common/app_installer.h index d5cb2ae..760d16c 100644 --- a/src/common/app_installer.h +++ b/src/common/app_installer.h @@ -9,7 +9,6 @@ #include "common/step/step.h" - namespace common_installer { class AppInstaller { @@ -28,14 +27,14 @@ class AppInstaller { int Run(); - protected: - std::unique_ptr context_; - private: AppInstaller(const AppInstaller& /*other*/) = delete; AppInstaller& operator=(const AppInstaller& /*other*/) = delete; + void EnsureSignalSend(); + std::list> steps_; + std::unique_ptr context_; }; } // namespace common_installer diff --git a/src/common/context_installer.h b/src/common/context_installer.h index 99ec0ce..bef7764 100644 --- a/src/common/context_installer.h +++ b/src/common/context_installer.h @@ -4,7 +4,6 @@ #define COMMON_CONTEXT_INSTALLER_H_ #include -#include #include #include @@ -12,6 +11,8 @@ #include #include +#include "common/pkgmgr_signal.h" + namespace common_installer { class ConfigData; @@ -76,8 +77,8 @@ class ContextInstaller { file_path_ = file_path; } - void set_pi(pkgmgr_installer* pi) { - pi_ = pi; + void set_pi(std::unique_ptr pi) { + pi_ = std::move(pi); } uid_t uid() const { return uid_; } @@ -89,7 +90,7 @@ class ContextInstaller { ConfigData* config_data() const { return config_data_.get(); } - pkgmgr_installer* pi() const { return pi_; } + PkgmgrSignal* pi() const { return pi_.get(); } const char* GetApplicationPath() const; const char* GetRootApplicationPath() const; @@ -123,7 +124,7 @@ class ContextInstaller { ConfigDataPtr config_data_; // data used to send signal - pkgmgr_installer *pi_; + std::unique_ptr pi_; }; } // namespace common_installer diff --git a/src/common/pkgmgr_signal.cc b/src/common/pkgmgr_signal.cc new file mode 100644 index 0000000..e3e64ff --- /dev/null +++ b/src/common/pkgmgr_signal.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#include "common/pkgmgr_signal.h" + +#include +#include + +#define DBG(msg) std::cout << "[PkgmgrSignal] " << msg << std::endl; +#define ERR(msg) std::cout << "[ERROR: PkgmgrSignal] " << msg << std::endl; + +namespace common_installer { + +PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi) + : pi_(pi), + state_(State::NOT_SENT) { +} + +bool PkgmgrSignal::sendStarted( + const std::string& type, const std::string& pkgid) { + if (state_ != State::NOT_SENT) { + return false; + } + + if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, + (pkgmgr_installer_get_request_type(pi_) != PKGMGR_REQ_UNINSTALL) + ? PKGMGR_INSTALLER_INSTALL_EVENT_STR + : PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, + type, pkgid)) { + return false; + } + state_ = State::STARTED; + return true; +} + +bool PkgmgrSignal::sendFinished( + Result result, const std::string& type, const std::string& pkgid) { + if (state_ != State::STARTED) { + return false; + } + if (!SendSignal( + PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid)) { + return false; + } + state_ = State::FINISHED; + return true; +} + +bool PkgmgrSignal::IsFinished() const { + return state_ == State::FINISHED; +} + +bool PkgmgrSignal::SendSignal( + const char* key, + const char* value, + const std::string& type, + const std::string& pkgid) const { + // send pkgmgr signal + if (pkgmgr_installer_send_signal( + pi_, + !type.empty() ? type.c_str(): "", + !pkgid.empty() ? pkgid.c_str() : "", + key, + value)) { + ERR("Fail to send pkgmgr signal"); + return false; + } + + DBG("Success to send pkgmgr signal PKGID=" << pkgid + << " KEY=" << key + << " VALUE=" << value); + return true; +} + +const char* PkgmgrSignal::GetResultKey(Result result) const { + switch (result) { + case Result::SUCCESS: + return PKGMGR_INSTALLER_OK_EVENT_STR; + case Result::FAILED: + return PKGMGR_INSTALLER_FAIL_EVENT_STR; + default: + assert(false && "Not Reached"); + } +} + +} // namespace common_installer diff --git a/src/common/pkgmgr_signal.h b/src/common/pkgmgr_signal.h new file mode 100644 index 0000000..f32db2d --- /dev/null +++ b/src/common/pkgmgr_signal.h @@ -0,0 +1,64 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PKGMGR_SIGNAL_H_ +#define COMMON_PKGMGR_SIGNAL_H_ + +#include + +#include +#include + +namespace common_installer { + +// +// Utility for sending signal to pkgmgr +// +// One installation process should not create more than one instance of this +// class. Object contains state of signaling and will report error if +// used in wrong way. +// +class PkgmgrSignal { + public: + enum class Result { + SUCCESS, + FAILED + }; + + explicit PkgmgrSignal(pkgmgr_installer* pi); + + bool sendStarted( + const std::string& type = std::string(), + const std::string& pkgid = std::string()); + bool sendFinished( + Result result, + const std::string& type = std::string(), + const std::string& pkgid = std::string()); + bool IsFinished() const; + + private: + enum class State { + NOT_SENT, + STARTED, + FINISHED + }; + + bool SendSignal( + const char* key, + const char* value, + const std::string& type = std::string(), + const std::string& pkgid = std::string()) const; + const char* GetResultKey(Result result) const; + + pkgmgr_installer* pi_; + State state_; + + // TODO(t.iwanek): use DISALLOW_COPY_AND_ASSIGN + PkgmgrSignal(const PkgmgrSignal&) = delete; + PkgmgrSignal& operator=(const PkgmgrSignal&) = delete; +}; + +} // namespace common_installer + +#endif // COMMON_PKGMGR_SIGNAL_H_ diff --git a/src/common/step/step_signal.cc b/src/common/step/step_signal.cc index 7ce189f..209552d 100644 --- a/src/common/step/step_signal.cc +++ b/src/common/step/step_signal.cc @@ -2,9 +2,6 @@ #include "common/step/step_signal.h" -#include -#include - #include #include "common/utils.h" @@ -15,55 +12,34 @@ namespace common_installer { namespace signal { -bool StepSignal::sendSignal(ContextInstaller* context, const std::string& key, - const std::string& value) { - if (!context->pi()) { - ERR("PkgmgrSingal not yet intialized"); - return false; - } - - if (key.empty() || value.empty()) { - DBG("key or value is empty"); - return false; - } - - // send pkgmgr signal - if (pkgmgr_installer_send_signal( - context->pi(), context->manifest_data()->type, - context->pkgid().c_str(), - key.c_str(), value.c_str())) { - ERR("Fail to send pkgmgr signal"); - return false; - } - - DBG("Success to send pkgmgr signal"); - return true; -} - Step::Status StepSignal::process() { - sendSignal(context_, PKGMGR_INSTALLER_START_KEY_STR, - PKGMGR_INSTALLER_INSTALL_EVENT_STR); + if (!context_->pi()->sendStarted( + context_->manifest_data()->type, context_->pkgid())) { + return Status::ERROR; + } DBG("Send Start"); return Status::OK; } Step::Status StepSignal::clean() { - sendSignal(context_, PKGMGR_INSTALLER_END_KEY_STR, - PKGMGR_INSTALLER_OK_EVENT_STR); + if (!context_->pi()->sendFinished( + PkgmgrSignal::Result::SUCCESS, + context_->manifest_data()->type, context_->pkgid())) { + return Status::ERROR; + } DBG("Send Success"); return Status::OK; } Step::Status StepSignal::undo() { - sendSignal(context_, PKGMGR_INSTALLER_END_KEY_STR, - PKGMGR_INSTALLER_FAIL_EVENT_STR); + if (!context_->pi()->sendFinished( + PkgmgrSignal::Result::FAILED, + context_->manifest_data()->type, context_->pkgid())) { + return Status::ERROR; + } DBG("Send Error"); return Status::OK; } - - - - } // namespace signal } // namespace common_installer diff --git a/src/common/step/step_signal.h b/src/common/step/step_signal.h index 8198360..5843294 100644 --- a/src/common/step/step_signal.h +++ b/src/common/step/step_signal.h @@ -19,10 +19,6 @@ class StepSignal : public Step { Status process() override; Status clean() override; Status undo() override; - - private: - bool sendSignal(ContextInstaller* data, const std::string& key, - const std::string& value); }; } // namespace signal