# Dependency
APPLY_PKG_CONFIG(${TARGET_PKG_UPGRADE} PUBLIC
PKGMGR_INFO_DEPS
+ PKGMGR_INSTALLER_DEPS
PKGMGR_PARSER_DEPS
TIZEN_DATABASE_DEPS
TZPLATFORM_DEPS
UNKNOWN
};
+enum class PkgUpgradeResult {
+ SKIPPED,
+ INSTALLED,
+ UNINSTALLED,
+ UPDATED,
+ FAILED,
+ UNKNOWN,
+};
+
class PkgContext {
public:
PkgContext(std::string id, std::string version, std::string type,
std::string GetVersion() const;
const BackendInvoker& GetBackendInvoker() const;
PkgVersionCmpResult CompareVersion(const PkgUpgrader& pkg) const;
+ PkgUpgradeResult GetResult() const;
virtual bool Upgrade() = 0;
+ protected:
+ PkgUpgradeResult result_;
+
private:
PkgType type_;
PkgLocation loc_;
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PKGMGR_SIGNAL_H_
+#define PKGMGR_SIGNAL_H_
+
+#include <pkgmgr_installer.h>
+
+#include <string>
+
+#include "common_type.hh"
+
+namespace common_fota {
+
+class PkgmgrSignal {
+ public:
+ PkgmgrSignal();
+ virtual ~PkgmgrSignal();
+
+ void SetTotalPkgs(int total_pkgs);
+ bool SendSignal(const std::string& pkgid, PkgUpgradeResult result);
+ bool SendInitialized();
+ bool SendFinished();
+ bool SendProgress();
+
+ private:
+ bool SendSignal(unsigned int progress);
+
+ pkgmgr_installer* pi_;
+ int count_;
+ int total_pkgs_;
+};
+
+} // common_fota
+
+#endif // PKGMGR_SIGNAL_H_
#include "file_logbackend.hh"
#include "pkg_finder.hh"
#include "pkg_upgrader.hh"
+#include "pkgmgr_signal.hh"
namespace common_fota {
std::list<std::unique_ptr<PkgUpgrader>> failure_list_;
std::string parser_db_;
std::string cert_db_;
+ PkgmgrSignal signal_;
};
} // common_fota
if (GetLocation() == PkgLocation::RW) {
if (!SetRwPkg(pkgid_)) {
LOG(ERROR) << "Failed to update pkg " << pkgid_;
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
LOG(INFO) << "Preloaded files of " << pkgid_ << " has been removed. "
<< "This package will be non-preload RW package";
}
+ result_ = PkgUpgradeResult::SKIPPED;
return true;
}
}
PkgUpgrader::PkgUpgrader(std::string id, std::string version)
- : type_(PkgType::UNKNOWN), loc_(PkgLocation::UNKNOWN),
- op_(PkgOperation::COMPLEX), id_(std::move(id)),
- version_(std::move(version)) {
+ : result_(PkgUpgradeResult::UNKNOWN), type_(PkgType::UNKNOWN),
+ loc_(PkgLocation::UNKNOWN), op_(PkgOperation::COMPLEX),
+ id_(std::move(id)), version_(std::move(version)) {
}
PkgType PkgUpgrader::GetType() const {
return backend_;
}
+PkgUpgradeResult PkgUpgrader::GetResult() const {
+ return result_;
+}
+
PkgVersionCmpResult PkgUpgrader::CompareVersion(
const PkgUpgrader& pkg) const {
pkgmgrinfo_version_compare_type compare = PMINFO_VERSION_OLD;
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pkgmgr_signal.hh"
+
+#include <pkgmgr_installer.h>
+
+#include <string>
+
+#include "common_type.hh"
+#include "logging.hh"
+
+namespace {
+
+const unsigned int kProgressRange = 100;
+
+} // namespace
+
+namespace common_fota {
+
+PkgmgrSignal::PkgmgrSignal() : count_(1), total_pkgs_(0) {
+ pi_ = pkgmgr_installer_new();
+ if (pi_ == nullptr)
+ LOG(ERROR) << "Failed to create pkgmgr installer";
+}
+
+PkgmgrSignal::~PkgmgrSignal() {
+ if (pi_ != nullptr)
+ pkgmgr_installer_free(pi_);
+}
+
+void PkgmgrSignal::SetTotalPkgs(int total_pkgs) {
+ total_pkgs_ = total_pkgs;
+}
+
+bool PkgmgrSignal::SendSignal(unsigned int progress) {
+ if (pi_ == nullptr) {
+ LOG(ERROR) << "pkgmgr installer is not created";
+ return false;
+ }
+
+ int ret = pkgmgr_installer_send_pkg_upgrade_signal(pi_, progress);
+ if (ret != 0) {
+ LOG(ERROR) << "pkgmgr_installer_send_pkg_upgrade_signal failed";
+ return false;
+ }
+ return true;
+}
+
+bool PkgmgrSignal::SendInitialized() {
+ LOG(DEBUG) << "Send initialized signal";
+ return SendSignal(0);
+}
+
+bool PkgmgrSignal::SendFinished() {
+ LOG(DEBUG) << "Send finished signal";
+ return SendSignal(kProgressRange);
+}
+
+bool PkgmgrSignal::SendProgress() {
+ if (count_ > total_pkgs_) {
+ LOG(WARNING) << "count should not be greater than total packages";
+ return false;
+ }
+ unsigned int progress = count_++ * kProgressRange / total_pkgs_;
+ LOG(DEBUG) << "Send progress: " << progress;
+ return SendSignal(progress);
+}
+
+} // namespace common_fota
if (old_pkg_.get() != nullptr) {
if (!old_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation of old RO package failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
}
if (new_pkg_.get() != nullptr) {
if (!new_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation of new RW package failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
}
+ result_ = PkgUpgradeResult::UPDATED;
return true;
}
if (result == PkgVersionCmpResult::UNKNOWN) {
LOG(ERROR) << "Failed to compare version of package("
<< new_pkg_->GetId() << ")";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
if (result == PkgVersionCmpResult::SAME) {
LOG(INFO) << new_pkg_->GetId() << " has same version("
<< new_pkg_->GetVersion() << "). Nothing to do.";
+ result_ = PkgUpgradeResult::SKIPPED;
return true;
}
}
if (!new_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
+ result_ = PkgUpgradeResult::UPDATED;
return true;
}
if (result == PkgVersionCmpResult::UNKNOWN) {
LOG(ERROR) << "Failed to compare version of package(" << new_pkg_->GetId()
<< ")";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
if (result == PkgVersionCmpResult::LOWER) {
LOG(INFO) << old_pkg_->GetId() << " has higher version("
<< old_pkg_->GetVersion() << ") already. Nothing to do.";
+ result_ = PkgUpgradeResult::SKIPPED;
return true;
}
if (!old_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation of old RW package failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
if (!new_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation of new RO package failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
+ result_ = PkgUpgradeResult::UPDATED;
return true;
}
if (result == PkgVersionCmpResult::UNKNOWN) {
LOG(ERROR) << "Failed to compare version of package("
<< new_pkg_->GetId() << ")";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
if (result == PkgVersionCmpResult::SAME) {
LOG(INFO) << new_pkg_->GetId() << " has same version("
<< new_pkg_->GetVersion() << "). Nothing to do.";
+ result_ = PkgUpgradeResult::SKIPPED;
return true;
}
}
if (new_pkg_->GetOperation() != PkgOperation::UNINSTALL &&
new_pkg_->GetOperation() != PkgOperation::UNINSTALL_KEEP_RW_DATA) {
- if (!UnzipPkgFromZip(new_pkg_->GetId()))
+ if (!UnzipPkgFromZip(new_pkg_->GetId())) {
+ result_ = PkgUpgradeResult::FAILED;
return false;
+ }
}
if (!new_pkg_->Upgrade()) {
LOG(ERROR) << "Upgrade operation failed";
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
+ result_ = PkgUpgradeResult::UPDATED;
return true;
}
}
bool SimpleUpgrader::Upgrade() {
- if (GetBackendInvoker().Run() == 0)
+ if (GetBackendInvoker().Run() == 0) {
+ if (GetOperation() == PkgOperation::UNINSTALL)
+ result_ = PkgUpgradeResult::UNINSTALLED;
+ else
+ result_ = PkgUpgradeResult::INSTALLED;
return true;
+ }
+ result_ = PkgUpgradeResult::FAILED;
return false;
}
RemoveBackupDbs();
return false;
}
+ signal_.SetTotalPkgs(list.size());
+ LOG(DEBUG) << "Found " << list.size() << " packages to upgrade";
auto priority_list = factory.MakePriorityList(finder, list);
+ // Send signal after initializing
+ if (!signal_.SendInitialized())
+ LOG(ERROR) << "Failed to send initialized signal";
ProcessList(priority_list);
- // send signal at this time?
ProcessList(list);
+
+ if (!signal_.SendFinished())
+ LOG(ERROR) << "Failed to send finished signal";
RemoveBackupDbs();
logger_->WriteLog(::utils::LogLevel::LOG_INFO, "", "Upgrade Done");
void Upgrader::ProcessList(list<unique_ptr<PkgUpgrader>>& list) {
for (auto& pkg : list) {
- if (pkg->Upgrade()) {
+ bool result = pkg->Upgrade();
+ if (!signal_.SendProgress())
+ LOG(ERROR) << "Failed to send progress signal";
+ if (result) {
LOG(DEBUG) << "upgrade success (" << pkg->GetId() << ")";
success_list_.push_back(move(pkg));
} else {