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
SET(SRCS
app_installer.cc
context_installer.cc
+ pkgmgr_signal.cc
security_registration.cc
step/step_unzip.cc
step/step_signature.cc
#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<PkgmgrSignal>(new PkgmgrSignal(pi)));
context_->set_request_type(request_type);
switch (request_type) {
case PKGMGR_REQ_INSTALL:
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<std::unique_ptr<Step>>::iterator it(steps_.begin());
}
}
}
+
+ EnsureSignalSend();
+
return ret;
}
#include "common/step/step.h"
-
namespace common_installer {
class AppInstaller {
int Run();
- protected:
- std::unique_ptr<ContextInstaller> context_;
-
private:
AppInstaller(const AppInstaller& /*other*/) = delete;
AppInstaller& operator=(const AppInstaller& /*other*/) = delete;
+ void EnsureSignalSend();
+
std::list<std::unique_ptr<Step>> steps_;
+ std::unique_ptr<ContextInstaller> context_;
};
} // namespace common_installer
#define COMMON_CONTEXT_INSTALLER_H_
#include <pkgmgr_parser.h>
-#include <pkgmgr_installer.h>
#include <unistd.h>
#include <sys/types.h>
#include <memory>
#include <string>
+#include "common/pkgmgr_signal.h"
+
namespace common_installer {
class ConfigData;
file_path_ = file_path;
}
- void set_pi(pkgmgr_installer* pi) {
- pi_ = pi;
+ void set_pi(std::unique_ptr<PkgmgrSignal> pi) {
+ pi_ = std::move(pi);
}
uid_t uid() const { return uid_; }
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;
ConfigDataPtr config_data_;
// data used to send signal
- pkgmgr_installer *pi_;
+ std::unique_ptr<PkgmgrSignal> pi_;
};
} // namespace common_installer
--- /dev/null
+// 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 <cassert>
+#include <iostream>
+
+#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
--- /dev/null
+// 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 <pkgmgr_installer.h>
+
+#include <memory>
+#include <string>
+
+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_
#include "common/step/step_signal.h"
-#include <pkgmgr-info.h>
-#include <unistd.h>
-
#include <iostream>
#include "common/utils.h"
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
Status process() override;
Status clean() override;
Status undo() override;
-
- private:
- bool sendSignal(ContextInstaller* data, const std::string& key,
- const std::string& value);
};
} // namespace signal