AppInstaller::AppInstaller(const char* package_type, PkgMgrPtr pkgmgr)
: pkgmgr_(pkgmgr), context_(new InstallerContext()),
- status_(Step::Status::OK), result_(Result::OK) {
+ status_(Step::Status::OK), result_(Result::OK), index_(0) {
context_->pkg_type.set(package_type);
context_->installation_mode.set(pkgmgr->GetInstallationMode());
}
void AppInstaller::Init() {
- switch (pkgmgr_->GetRequestType()) {
+ // for multi installer
+ context_->index.set(index_);
+ pkgmgr_->SetAppQueryInterface(index_);
+
+ switch (pkgmgr_->GetRequestType(index_)) {
case RequestType::Install:
InstallSteps();
break;
}
AppInstaller::Result AppInstaller::Run() {
- failure_logger_ =
- std::shared_ptr<utils::FileLogBackend>(new utils::FileLogBackend(
- kLogFileName, kLogRotationSize, kLogMaximumRotation));
- ::utils::LogCore::GetCore().AddLogBackend(failure_logger_);
-
Process();
if (it_ != steps_.end() && result_ == Result::ERROR) {
LOG(ERROR) << "Failure occurs in step: " << (*it_)->name();
info_file.close();
}
- LogHistory(status_ == Step::Status::OK ? true : false);
-
return result_;
}
AppInstaller::Result AppInstaller::Process() {
Init();
+ failure_logger_ =
+ std::shared_ptr<utils::FileLogBackend>(new utils::FileLogBackend(
+ kLogFileName, kLogRotationSize, kLogMaximumRotation));
+ ::utils::LogCore::GetCore().AddLogBackend(failure_logger_);
+
unsigned total_steps = steps_.size();
unsigned current_step = 1;
AppInstaller::Result AppInstaller::Undo() {
do {
+ if (it_ == steps_.end())
+ --it_;
if (SafeExecute(*it_, &Step::undo, "undo") != Step::Status::OK) {
LOG(ERROR) << "Error during undo operation(" << (*it_)->name()
<< "), but continuing...";
sync();
failure_logger_->WriteLogToFile();
+ // Undo will be invoked when other installer fails when multi-install, but the
+ // status of current installer can be ok. We need to change this to proper
+ // error code to notify that entire installation was failed to listener.
+ // TODO(jeremy.jang): Need some other error for multi-install failure?
+ if (status_ == Step::Status::OK)
+ status_ = Step::Status::ERROR;
SendFinished(status_);
+ LogHistory(false);
+
return result_;
}
} while (it_-- != steps_.begin());
sync();
+ LogHistory(true);
+
return result_;
}
return steps_.size();
}
+ void SetIndex(int index) {
+ index_ = index;
+ }
+
protected:
PkgMgrPtr pkgmgr_;
std::unique_ptr<InstallerContext> context_;
Result result_;
void LogHistory(bool success);
+ int index_;
+
SCOPE_LOG_TAG(AppInstaller)
DISALLOW_COPY_AND_ASSIGN(AppInstaller);
* @brief Storage where package to be installed
*/
Property<Storage> storage;
+
+ /**
+ * @brief Index of current request
+ */
+ Property<int> index;
};
} // namespace common_installer
pkgmgr_installer_free(pi_);
}
-void PkgMgrInterface::SetAppQueryInterface(AppQueryInterface* interface) {
- query_interface_ = interface;
+// method name?
+bool PkgMgrInterface::SetAppQueryInterface(int idx) {
+ auto it = query_interface_map_.find(idx);
+ if (it == query_interface_map_.end()) {
+ if (!query_interface_) {
+ LOG(ERROR) << "Cannot find query interface for index(" << idx << ")";
+ return false;
+ } else {
+ // using legacy query interface (for single pkg installer)
+ return true;
+ }
+ }
+ query_interface_ = it->second;
+ return true;
}
-RequestType PkgMgrInterface::GetRequestType() const {
+void PkgMgrInterface::AddAppQueryInterface(
+ int idx, AppQueryInterface* interface) {
+ query_interface_map_.emplace(idx, interface);
+}
+
+RequestType PkgMgrInterface::GetRequestType(int idx) const {
if (!query_interface_)
return RequestType::Unknown;
if (!is_app_installed_) {
is_app_installed_ =
- query_interface_->IsPkgInstalled(GetRequestInfo(), GetUid());
+ query_interface_->IsPkgInstalled(GetRequestInfo(idx), GetUid());
}
switch (pkgmgr_installer_get_request_type(pi_)) {
+ case PKGMGR_REQ_UPGRADE :
case PKGMGR_REQ_INSTALL : {
- auto request_info = GetRequestInfo();
+ auto request_info = GetRequestInfo(idx);
if (request_info.empty())
return RequestType::Unknown;
bool is_delta = IsDeltaPkg(request_info);
if (is_delta) {
return RequestType::Delta;
} else {
- std::string pkgid = query_interface_->GetPkgId(GetRequestInfo());
+ std::string pkgid = query_interface_->GetPkgId(GetRequestInfo(idx));
uid_t uid = GetUid();
ci::PkgQueryInterface pkg_query(pkgid, uid);
if (!GetIsPreloadRequest() &&
}
}
case PKGMGR_REQ_UNINSTALL: {
- std::string pkgid = GetRequestInfo();
+ std::string pkgid = GetRequestInfo(idx);
uid_t uid = GetUid();
ci::PkgQueryInterface pkg_query(pkgid, uid);
if (pkg_query.IsSystemPackage() &&
return pkgmgr_installer_get_uid(pi_);
}
-std::string PkgMgrInterface::GetRequestInfo() const {
- const char* request_info = pkgmgr_installer_get_request_info(pi_);
+std::string PkgMgrInterface::GetRequestInfo(int idx) const {
+ const char* request_info = pkgmgr_installer_get_request_info_at(pi_, idx);
if (!request_info)
return {};
else
return (pkgmgr_installer_get_skip_optimization(pi_) == 1);
}
+int PkgMgrInterface::GetRequestInfoCount() const {
+ return pkgmgr_installer_get_request_info_count(pi_);
+}
+
} // namespace common_installer
#include <boost/optional/optional.hpp>
#include <manifest_parser/utils/logging.h>
#include <pkgmgr_installer.h>
+
+#include <map>
#include <memory>
#include <string>
*/
class PkgMgrInterface {
public:
- void SetAppQueryInterface(AppQueryInterface* interface);
+ /**
+ * Set current AppQueryInterface for request
+ *
+ * \param idx index of request
+ *
+ * \return True if setting was success. Otherwise, return false
+ */
+ bool SetAppQueryInterface(int idx);
+
+ /**
+ * Add AppQueryInterface for request
+ *
+ * \param idx index of request
+ * \param interface AppQueryInterface for request
+ */
+ void AddAppQueryInterface(int idx, AppQueryInterface* interface);
+
/**
* Returns Request type passed from pkgmgr_installer
*
+ * \param idx index of request
+ *
* \return request type retrieved from pkgmgr_installer
*/
- RequestType GetRequestType() const;
+ RequestType GetRequestType(int idx = 0) const;
/**
* Returns uid passed from pkgmgr_installer
/**
* Returns Request info passed from pkgmgr_installer
*
+ * \param idx index of request
+ *
* \return request info retrieved from pkgmgr_installer
*/
- std::string GetRequestInfo() const;
+ std::string GetRequestInfo(int idx = 0) const;
/**
* Creates PkgMgrInterface
bool GetSkipOptimization() const;
/**
+ * Returns the number of request info count.
+ *
+ * \return The number of request info count.
+ */
+ int GetRequestInfoCount() const;
+
+ /**
* Get Raw pointer to pkgmgr_installer object
* NOTE: It should not be used (PkgMgrInterface can destroy it
*
PkgmgrInstallerInterface* pkgmgr_installer_interface_;
AppQueryInterface* query_interface_;
+ std::map<int, AppQueryInterface*> query_interface_map_;
SCOPE_LOG_TAG(PkgMgrInterface)
DISALLOW_COPY_AND_ASSIGN(PkgMgrInterface);
namespace common_installer {
-PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi)
- : pi_(pi), request_type_(RequestType::Unknown), error_message_sent_(false) {
+ : pi_(pi), state_(State::NOT_SENT), request_type_(RequestType::Unknown),
+ error_message_sent_(false) {
uid_ = pkgmgr_installer_get_uid(pi_);
request_mode_ = GetRequestMode(uid_);
}
bool SetupUserList(const std::string& pkgid);
pkgmgr_installer* pi_;
- static State state_;
+ State state_;
RequestType request_type_;
RequestMode request_mode_;
uid_t uid_;
switch (request_type) {
case RequestType::Install:
case RequestType::Update:
- context_->file_path.set(pkgmgr_->GetRequestInfo());
+ context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
if (!pkgmgr_->GetTepPath().empty()) {
context_->tep_path.set(pkgmgr_->GetTepPath());
context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
SetupIsPartialRW();
SetupIsKeepRWData();
SetupIsForceRemoval();
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
context_->file_path.set(kStrEmpty);
break;
case RequestType::Reinstall:
context_->unpacked_dir_path.set(
bf::path(tzplatform_getenv(TZ_SDK_TOOLS)) / "tmp" /
- pkgmgr_->GetRequestInfo());
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ pkgmgr_->GetRequestInfo(context_->index.get()));
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
context_->file_path.set(kStrEmpty);
break;
case RequestType::Delta:
context_->unpacked_dir_path.set(kStrEmpty);
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
- context_->file_path.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
+ context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
break;
case RequestType::Move:
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
SetupMoveType();
break;
case RequestType::Recovery:
- context_->file_path.set(pkgmgr_->GetRequestInfo());
+ context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
break;
case RequestType::MountInstall:
case RequestType::MountUpdate:
- context_->file_path.set(pkgmgr_->GetRequestInfo());
+ context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
if (!pkgmgr_->GetTepPath().empty()) {
context_->tep_path.set(pkgmgr_->GetTepPath());
context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
if (request_type == RequestType::ManifestPartialInstall ||
request_type == RequestType::ManifestPartialUpdate)
SetupIsPartialRW();
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
bf::path xml_path =
bf::path(getUserManifestPath(context_->uid.get(),
context_->is_readonly_package.get()))
break;
}
case RequestType::ReadonlyUpdateInstall:
- context_->file_path.set(pkgmgr_->GetRequestInfo());
+ context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
if (!pkgmgr_->GetTepPath().empty()) {
context_->tep_path.set(pkgmgr_->GetTepPath());
context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
}
break;
case RequestType::ReadonlyUpdateUninstall: {
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
bf::path original_path =
bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
context_->unpacked_dir_path.set(original_path);
}
case RequestType::DisablePkg:
case RequestType::EnablePkg:
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
break;
case RequestType::MigrateExtImg: {
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
break;
}
case RequestType::RecoverDB: {
- context_->pkgid.set(pkgmgr_->GetRequestInfo());
+ context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
break;
}
default:
}
void StepConfigure::SetupRequestType() {
- context_->request_type.set(pkgmgr_->GetRequestType());
+ context_->request_type.set(pkgmgr_->GetRequestType(context_->index.get()));
}
void StepConfigure::SetupFileCreationMask() {